2010-06-30 122 views
3

我不确定这是正确的方式,但我使用这个函数进行输入。例如联系表格:防止PHP中的跨站点脚本

RemoveXSS(mysql_real_escape_string($_POST['input'])) 

但随着扫描,有这样的结果:

Parameter Name: Query Based 
Parameter Type: FullQueryString 
Attack Pattern: /"ns="alert(0x00058B) 

上述网址点击,当我不能看到页面什么。但是,我的代码有什么问题。

///////////

function RemoveXSS($val) 
{ 

$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=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&#X3A &#X61&#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29> 
$search = 'abcdefghijklmnopqrstuvwxyz'; 
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
$search .= '[email protected]#$%^&*()'; 
$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 

    // &#x0040 @ search for the hex values 
    $val = preg_replace('/(&#[xX]0{0,8}' . dechex(ord($search[$i])) . ';?)/i', $search[$i], 
     $val); // with a ; 
    // &#00064 @ 0{0,7} matches '0' zero to seven times 
    $val = preg_replace('/(&#0{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{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; 
} 

在此先感谢

+0

你的问题是什么? – RageZ 2010-06-30 09:18:47

回答

8

这似乎是巨大的矫枉过正我。有什么问题像htmlspecialchars($val)filter_var($val, FILTER_SANITIZE_STRING);

+1

我完全同意...... – helle 2010-06-30 09:23:55

+0

你是对的,我在搜索安全解决方案时发现了这个功能。 – TheNone 2010-06-30 09:41:34

+0

with pleasure seengee;) – TheNone 2010-06-30 16:34:50

3

你正在混合保护从XSS(注入到浏览器)和SQL注入。

mysql_real_escape_string用于转义要在SQL查询中使用的字符串,例如,以避免在“SELECT * FROM foo WHERE name =”中注入$ name

“坏”字符串的示例将是一个将被执行的SQL命令。

对于浏览器输出,可以使用htmlentities()或htmlspecialchars()来转义从易受XSS输出的字符串。

“坏”字符串的例子是:注册名称包含HTML标记的用户。如果您在不转义的情况下输出此用户的名称,则HTML标签将被注入。

没有理由手动过滤每个可能的JavaScript属性或标记 - 无论如何你可能会错过一些。ヶ辆()/用htmlspecialchars()会逃脱类似

<script language="JavaScript"> 

&lt;script language="JavaScript"&gt; 

这样的代码只得到安全的浏览器,而不是被执行的显示。

总结是:有两种类型的转义,一种是SQL,一种是HTML。混合它们没有意义。

+0

'“SELECT * FROM foo WHERE name =”。mysql_real_escape_string($ name);'仍然容易受到sql注入的影响。 – rook 2010-06-30 15:09:31

2

混合sql注入和xss过滤器是一个坏主意。他们是非常不同的攻击,他们使用非常不同的控制字符。

如果您只是想阻止XSS使用htmlspeiclchars($var,ENT_QUOTES);。如果您只想允许安全的HTML,请使用HTML Purifier

如果你想停止sql注入使用带有PDO的参数化查询。

+0

白痴,我糊涂了!感谢您的帮助(接受100万次) – TheNone 2010-06-30 16:43:46