Created
November 7, 2013 20:46
-
-
Save cyc0der/7361578 to your computer and use it in GitHub Desktop.
PHP anti XSS for MySQL queries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function db_query($db_string, $file=null, $line=null) | |
{ | |
// One more query.... | |
$db_count = !isset($db_count) ? 1 : $db_count + 1; | |
$clean = ''; | |
$old_pos = 0; | |
$pos = -1; | |
while (true) | |
{ | |
$pos = strpos($db_string, '\'', $pos + 1); | |
if ($pos === false) | |
break; | |
$clean .= substr($db_string, $old_pos, $pos - $old_pos); | |
while (true) | |
{ | |
$pos1 = strpos($db_string, '\'', $pos + 1); | |
$pos2 = strpos($db_string, '\\', $pos + 1); | |
if ($pos1 === false) | |
break; | |
elseif ($pos2 == false || $pos2 > $pos1) | |
{ | |
$pos = $pos1; | |
break; | |
} | |
$pos = $pos2 + 1; | |
} | |
$clean .= ' %s '; | |
$old_pos = $pos + 1; | |
} | |
$clean .= substr($db_string, $old_pos); | |
$clean = trim(strtolower(preg_replace(array('~\s+~s', '~/\*!40001 SQL_NO_CACHE \*/~', '~/\*!40000 USE INDEX \([A-Za-z\_]+?\) \*/~'), array(' ', '', ''), $clean))); | |
// We don't use UNION in SMF, at least so far. But it's useful for injections. | |
if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0) | |
$fail = true; | |
// Comments? We don't use comments in our queries, we leave 'em outside! | |
elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, ';') !== false) | |
$fail = true; | |
// Trying to change passwords, slow us down, or something? | |
elseif (strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0) | |
$fail = true; | |
elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0) | |
$fail = true; | |
// Sub selects? We don't use those either. | |
elseif (preg_match('~\([^)]*?select~s', $clean) != 0) | |
$fail = true; | |
if (!empty($fail)) | |
{ | |
die('Hacking attempt...<br />file:"'.$file .'"<br />line:"'.$line.'"'); | |
} | |
//echo $db_string.'<br />'. | |
$ret = mysql_query($db_string); | |
if ($ret === false && $file !== false){ | |
die('MySQL error:<br />file:"'.$file .'"<br />line:"'.$line.'"'); | |
} | |
return $ret; | |
} | |
function noXSS($val) { | |
$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val); | |
$search = 'abcdefghijklmnopqrstuvwxyz'; | |
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; | |
$search .= '1234567890!@#$%^&*()'; | |
$search .= '~`";:?+/={}[]-_|\'\\'; | |
for ($i = 0; $i < strlen($search); $i++) { | |
$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ; | |
$val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; | |
}; | |
$ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base','union'); | |
$ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload'); | |
$ra = array_merge($ra1, $ra2); | |
$found = true; | |
while ($found == true) { | |
$val_before = $val; | |
for ($i = 0; $i < sizeof($ra); $i++) { | |
$pattern = '/'; | |
for ($j = 0; $j < strlen($ra[$i]); $j++) { | |
if ($j > 0) { | |
$pattern .= '('; | |
$pattern .= '(&#[xX]0{0,8}([9ab]);)'; | |
$pattern .= '|'; | |
$pattern .= '|(�{0,8}([9|10|13]);)'; | |
$pattern .= ')*'; | |
} | |
$pattern .= $ra[$i][$j]; | |
} | |
$pattern .= '/i'; | |
$replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag | |
$val = preg_replace($pattern, $replacement, $val); // filter out the hex tags | |
if ($val_before == $val) { | |
$found = false; | |
}; | |
}; | |
}; | |
return mysql_escape_string($val); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment