【发布时间】:2011-09-16 23:14:22
【问题描述】:
我已经在网上搜索了几天,试图弄清楚这一点,但得到的答案相互矛盾。
是否有针对 PHP 的库、类或函数可以针对 XSS 安全地清理/编码字符串?它需要定期更新以应对新的攻击。
我有几个用例:
用例 1) 我有一个纯文本字段,比如名字或姓氏
- 用户在字段中输入文本并提交表单
- 在将其保存到数据库之前,我想 a) 修剪前面的所有空白并 字符串的结尾,并且 b) 从输入中删除所有 HTML 标记。这是一个名称文本字段,其中不应包含任何 HTML。
- 然后我将使用 PDO 准备语句将其保存到数据库中。
我想我可以只做trim() 和strip_tags() 然后使用Sanitize Filter 或带有字符白名单的RegEx。他们真的需要像!和 ?或 < > 在他们的名字中,不是真的。
用例 2) 当将内容从以前保存的数据库记录(或以前提交的表单)输出到视图/HTML 时,我想彻底清理它以用于 XSS。 注意:在用例 1 中它可能已经或可能没有经过过滤步骤,因为它可能是不同类型的输入,因此假设没有进行任何清理。
最初我虽然 HTMLPurifier 可以完成这项工作,但似乎 不是I posed the question to their support 时我需要的:
这是试金石:如果用户提交
<b>foo</b>,它应该显示为<b>foo</b>还是 foo?如果是前者,则不需要 HTML Purifier。
所以我宁愿它显示为<b>foo</b>,因为我不希望为简单的文本字段显示任何 HTML 或执行任何 JavaScript。
所以我一直在寻找可以为我完成这一切的功能。我偶然发现了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 方法的第三个参数是要在转换中使用的字符集。现在我的站点/数据库是 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 输入...
如果有一些库或开源 PHP 框架可以正确地进行 XSS 保护,我很想看看他们是如何在代码中做到这一点的。
非常感谢任何帮助,对于长篇文章感到抱歉!
【问题讨论】:
-
我真的认为你想多了,正如 Phihag 含蓄地指出的那样,你不应该或不需要两次清理输入。您要么在数据库中清理它(不明智,因为您不会注意到正在发生攻击),要么在将其输出给用户之前对其进行清理。
-
@gnur 好吧,我正在清理一些字段,然后再进入数据库以保持一些数据完整性。我想如果检测到脚本/HTML 代码,我可以将它们重定向回页面,并让它们在重新提交之前清理输入。我对某些字段(例如用户名)执行此操作,因为用户名只能是字母数字。是否值得尝试检测 XSS 尝试提交并将它们记录在我的应用程序中?我打算在上线之前将 Mod Security 放在网络服务器的前面。我想这会受到一些攻击。
标签: php security xss filtering sanitization