Created
October 12, 2017 09:28
-
-
Save jorben/b8862df0bcb91b96370de7f8526276a2 to your computer and use it in GitHub Desktop.
php xss过滤
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 removeXSS($val) { | |
// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed | |
// this prevents some character re-spacing such as <java\0script> | |
// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs | |
$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val); | |
// straight replacements, the user should never need these since they're normal characters | |
// this prevents like <IMG SRC=@avascript:alert('XSS')> | |
$search = 'abcdefghijklmnopqrstuvwxyz'; | |
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; | |
$search .= '1234567890!@#$%^&*()'; | |
$search .= '~`";:?+/={}[]-_|\'\\'; | |
for ($i = 0; $i < strlen($search); $i++) { | |
// ;? matches the ;, which is optional | |
// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars | |
// @ @ search for the hex values | |
$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ; | |
// @ @ 0{0,7} matches '0' zero to seven times | |
$val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; | |
} | |
// now the only remaining whitespace attacks are \t, \n, and \r | |
$ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base'); | |
$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; // keep replacing as long as the previous round replaced something | |
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) { | |
// no replacements were made, so exit the loop | |
$found = false; | |
} | |
} | |
} | |
return $val; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment