2009-08-26 107 views
36

有谁知道从表单过滤通用输入的功能吗? Zend_Filter_input似乎需要事先了解输入内容,我担心使用诸如HTML Purifier之类的东西会对性能产生巨大影响。PHP中的XSS过滤功能

什么是这样的:http://snipplr.com/view/1848/php--sacar-xss/

非常感谢任何输入。

+2

HTMLPUrifier可能需要一些资源,但你可能没有那么多的内容张贴? (例如,比较咨询的内容);;如果您在将数据保存到数据库时运行HTMLPurifier,而不是从数据库读取数据时运行它,则可能是好的... – 2009-08-26 19:02:18

回答

69

简单的方法?使用:

$str = strip_tags($input); 

您还可以使用filter_var()为:

$str = filter_var($input, FILTER_SANITIZE_STRING); 

filter_var()的好处是,你可以控制的行为,例如,剥离或编码低和高的字符。

这里是一个sanitizing filters的列表。

+3

谢谢 - 不知道关于filter_var() – codecowboy 2009-08-27 06:57:15

+0

那么这是最好的方法还是HTML纯化器最大限度地提高安全性的方法。 – andho 2010-10-04 17:17:58

+13

虽然cletus通常倾向于点,但使用普通的'strip_tags()'是一个巨大的疏忽和安全问题。请详细阅读以下内容http://htmlpurifier.org/comparison#striptags – 2011-04-27 12:15:02

23

黑客用于XSS攻击的方式有很多,PHP的内置函数不会响应各种XSS攻击。因此,诸如strip_tags,filter_var,mysql_real_escape_string,htmlentities,htmlspecialchars等函数并不能保护我们100%。您需要一个更好的机制,这里是什么解决方案:

function xss_clean($data) 
{ 
// Fix &entity\n; 
$data = str_replace(array('&','<','>'), array('&','<','>'), $data); 
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data); 
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data); 
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8'); 

// Remove any attribute starting with "on" or xmlns 
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data); 

// Remove javascript: and vbscript: protocols 
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data); 
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data); 
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data); 

// Only works in IE: <span style="width: expression(alert('Ping!'));"></span> 
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data); 
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data); 
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data); 

// Remove namespaced elements (we do not need them) 
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data); 

do 
{ 
    // Remove really unwanted tags 
    $old_data = $data; 
    $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data); 
} 
while ($old_data !== $data); 

// we are done... 
return $data; 
} 
+3

嘿@Sarfraz是你的功能真的很安全吗? – Yakup 2011-01-18 15:21:36

+0

你还应该在*之前添加* urldecode *这个脚本不工作,例如%22%3E%3Cscript%3Ealert('try_xss');%3C/script%3E – 2011-01-18 15:21:45

+1

提供此代码的更新由Christian Stocker提供:http://blog.liip.ch/archive/2008/09/10/missed-case-in-externalinput-php-resulting-in-viable-xss-attacks.html – 2011-04-27 12:37:23

7

最好的和安全的方式是使用HTML净化器。按照这个链接了解如何在Zend Framework中使用它。

HTML Purifier with Zend Framework

+7

但是dammmmn是那个图书馆臃肿。 – 2011-04-27 12:40:57

+0

它可能会膨胀,但是当你真的需要核选项来过滤它时,它是最好的。 – LaXDragon 2016-06-24 19:44:14

2
function clean($data){ 
    $data = rawurldecode($data); 
    return filter_var($data, FILTER_SANITIZE_SPEC_CHARS); 
} 
+1

不起作用。但'$ data = filter_var($ _ GET ['data'],FILTER_SANITIZE_STRING);'工作。 – 2013-12-06 17:07:37

0

根据www.mcafeesecure.com一般解容易受到跨站点脚本(XSS)筛选器功能可以是:

function xss_cleaner($input_str) { 
    $return_str = str_replace(array('<','>',"'",'"',')','('), array('&lt;','&gt;','&apos;','&#x22;','&#x29;','&#x28;'), $input_str); 
    $return_str = str_ireplace('%3Cscript', '', $return_str); 
    return $return_str; 
} 
+0

以前接受并高度赞成的答案提供了一个干净而简短的解决方案。你的解决方案为这个答案增加了什么?检查这个[metaSO问题](http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question)和[Jon Skeet:Coding Blog]( http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx)如何给出正确的答案。 – Yaroslav 2012-10-11 12:07:58

3

我有类似的问题。我需要用户的HTML内容提交到个人资料页与一个伟大的所见即所得的编辑器(!Redactorjs),我写了下面的函数来清洁提交的HTML:

<?php function filterxss($str) { 
//Initialize DOM: 
$dom = new DOMDocument(); 
//Load content and add UTF8 hint: 
$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">'.$str); 
//Array holds allowed attributes and validation rules: 
$check = array('src'=>'#(http://[^\s]+(?=\.(jpe?g|png|gif)))#i','href'=>'|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i'); 
//Loop all elements: 
foreach($dom->getElementsByTagName('*') as $node){ 
    for($i = $node->attributes->length -1; $i >= 0; $i--){ 
     //Get the attribute: 
     $attribute = $node->attributes->item($i); 
     //Check if attribute is allowed: 
     if(in_array($attribute->name,array_keys($check))) { 
      //Validate by regex:  
      if(!preg_match($check[$attribute->name],$attribute->value)) { 
       //No match? Remove the attribute 
       $node->removeAttributeNode($attribute); 
      } 
     }else{ 
      //Not allowed? Remove the attribute: 
      $node->removeAttributeNode($attribute); 
     } 
    } 
} 
var_dump($dom->saveHTML()); } ?> 

的$检查数组保存所有允许的属性和验证规则。也许这对你们中的一些人有用。我没有测试尚未,所以提示欢迎

0

尝试使用清洁XSS

xss_clean($data): "><script>alert(String.fromCharCode(74,111,104,116,111,32,82,111,98,98,105,101))</script> 
1

htmlspecialchars()是完全足够显示在HTML表单过滤用户输入。

-1

我发现我的问题的解决方案与德国元音的职位。要完全清洗(杀死)的职位提供,我编码输入数据:

*$data = utf8_encode($data); 
    ... function ...* 

,最后我解码输出,以获得正确的符号:

*$data = utf8_decode($data);* 

现在后经过过滤器功能和我得到一个正确的结果...