安全的XSS清洁功能(定期更新)

时间:2011-06-17 07:03:17

标签: php security xss filtering sanitization

我现在一直在网上打猎几天试图解决这个问题,但得到了相互矛盾的答案。

是否有PHP的库,类或函数可以安全地清理/编码针对XSS的字符串?它需要定期更新以应对新的攻击。<​​/ strong>

我有几个用例:

用例1)我有一个纯文本字段,比如名字或姓氏

  • 用户在字段中输入文字并提交表单
  • 在将此文件保存到数据库之前,我想 a)修剪前面的任何空格 字符串的结尾, b)从输入中删除所有HTML标记。这是一个名称文本字段,它们不应包含任何HTML。
  • 然后我将使用PDO预处理语句将其保存到数据库中。

我想我可以trim()strip_tags()然后使用Sanitize Filter或RegEx和白名单字符。他们真的需要像这样的人物!和?或者< >在他们的名字中,而不是真的。

用例2)当从先前保存的数据库记录(或从先前提交的表单)输出内容到View / HTML时,我想彻底清除它以获取XSS。 NB:它可能已经或可能没有经过用例1中的过滤步骤,因为它可能是一种不同类型的输入,因此假设没有进行消毒。

最初我虽然HTMLPurifier会完成这项工作,但因为它似乎而不是I posed the question to their support时我需要的东西:

  

以下是试金石:如果用户提交<b>foo</b>它应显示为<b>foo</b>还是 foo ?如果是前者,则不需要HTML Purifier。

所以我宁愿它显示为<b>foo</b>,因为我不希望为简单的文本字段或任何执行的JavaScript显示任何HTML。

所以我一直在寻找能够为我做这一切的功能。我偶然发现了我猜测的xss_clean method used by Kohana 3.0,但只有当你想保留HTML时才会这样。它现在已经从Kohana 3.1中弃用,因为它们已经用HTMLPurifier取代了它。所以我猜你应该做HTML::chars(),而只做this code

public static function chars($value, $double_encode = TRUE)
{
    return htmlspecialchars( (string) $value, ENT_QUOTES, Kohana::$charset, $double_encode);
}

现在显然你应该使用htmlentities代替in quite a few places in Stack Overflow,因为它比htmlspecialchars更安全。

  • 那我该如何使用htmlentities呢? 正常?
  • 这就是我需要的全部吗?
  • 如何防止列出here列出的攻击发送的十六进制,十进制和base64编码值?

现在我看到htmlentities方法的第3个参数是转换中使用的字符集。现在我的站点/ db是UTF-8,但是表单提交的数据可能不是UTF-8编码,也许他们提交了ASCII或HEX,所以我可能需要先将其转换为UTF-8?这意味着一些代码如:

$encoding = mb_detect_encoding($input);
$input = mb_convert_encoding($input, 'UTF-8', $encoding);
$input = htmlentities($input, ENT_QUOTES, 'UTF-8');

是或否?然后我仍然不确定如何防止十六进制,十进制和base64可能的XSS输入......

如果有一些可以正确进行XSS保护的库或开源PHP框架,我很想看看它们是如何在代码中完成的。

任何帮助都非常感谢,对不起,很长的帖子!

2 个答案:

答案 0 :(得分:24)

回答大胆的问题:是的,有。它被称为htmlspecialchars

  

需要定期更新   反击新攻击。

防止XSS攻击的正确方法并非抵御特定攻击,过滤/清理数据,而是在任何地方正确编码

htmlspecialchars(或htmlentities)结合合理的字符编码决策(即UTF-8)和字符编码的明确规范足以防止所有XSS攻击。幸运的是,在没有显式编码的情况下调用htmlspecialchars(然后假定ISO-8859-1)也适用于UTF-8。如果要明确说明,请创建辅助函数:

// Don't forget to specify UTF-8 as the document's encoding
function htmlEncode($s) {
    return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}

哦,并解决形式问题:不要试图检测编码,它一定会失败。相反,请以UTF-8形式提供表格。每个浏览器都会以UTF-8发送用户输入。

解决具体问题:

  

(...)你应该使用   htmlentities因为htmlspecialchars   易受UTF-7 XSS漏洞攻击。

只有在浏览器认为文档是以UTF-7编码时,才能应用UTF-7 XSS漏洞。将文档编码指定为UTF-8(在HTTP标头/ <head>之后的元标记中)可以防止这种情况发生。

  

另外,如果我没有检测到编码,   什么是阻止攻击者下载   html文件,然后将其更改为   然后是UTF-7或其他一些编码   将POST请求提交回我的   来自改变的html页面的服务器?

此攻击情形不必要地复杂。攻击者可以制作一个UTF-7字符串,无需下载任何内容。

如果您接受攻击者的POST(即您接受匿名公共用户输入),您的服务器只会将UTF-7字符串解释为奇怪的UTF-8字符串。这不是问题,攻击者的帖子只会出现乱码。攻击者可以通过提交“grfnlk”一百次来达到同样的效果(发送奇怪的文本)。

  

如果我的方法仅适用于UTF-8,那么XSS攻击将通过,不是吗?

不,它不会。编码不是魔术。编码只是解释二进制字符串的一种方法。例如,字符串“ö”在UTF-7中编码为(十六进制)2B 41 50 59(在UTF-8中编码为C3 B6)。将2B 41 50 59解码为UTF-8会产生“+ APY” - 无害,看似随机的字符。

  

htmlentities如何防止HEX或其他XSS攻击?

十六进制数据将被输出。发送“3C”的攻击者将发布消息“3C”。如果您主动尝试解释十六进制输入,则“3C”可以成为<,例如,主动将它们映射到unicode代码点然后输出它们。这只是意味着如果您接受的是纯UTF-8(例如base32编码的UTF-8)中的数据,您首先必须解压缩编码,然后使用{{1在将它包含在HTML代码之前。

答案 1 :(得分:0)

许多安全工程师建议将此库用于此特定问题:

https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API