我现在一直在网上打猎几天试图解决这个问题,但得到了相互矛盾的答案。
是否有PHP的库,类或函数可以安全地清理/编码针对XSS的字符串?它需要定期更新以应对新的攻击。</ strong>
我有几个用例:
用例1)我有一个纯文本字段,比如名字或姓氏
我想我可以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方法的第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框架,我很想看看它们是如何在代码中完成的。
任何帮助都非常感谢,对不起,很长的帖子!
答案 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