我正在运行一个评论系统,我想接受常规的、未格式化的文本。
我不想要任何太复杂的东西,所以我只想搜索并将所有内容替换<为空格(通过正则表达式或简单for循环),所以<script src="http://malicioussite.com">只会显示为script src="http://malicioussite.com".
有什么理由不这样做吗?
黑客仍然可以逃脱 XSS 吗?
我正在运行一个评论系统,我想接受常规的、未格式化的文本。
我不想要任何太复杂的东西,所以我只想搜索并将所有内容替换<为空格(通过正则表达式或简单for循环),所以<script src="http://malicioussite.com">只会显示为script src="http://malicioussite.com".
有什么理由不这样做吗?
黑客仍然可以逃脱 XSS 吗?
在所有情况下替换<和>字符是不够的。当然,它会阻止任何用户打开 HTML 标签,但这不会阻止他/她在 HTML 标签中注入 HTML 属性。
例如,让我们看一个解析器,它转换[img=XXX]为<img src="XXX" />,只替换<and >。
恶意用户可以输入[img=X" onerror="alert(1)],解析器会返回:
<img src="X" onerror="alert(1)" />
并且警报会提示,这意味着可能发生 XSS 攻击。
可能就够了,也可能不够,但这绝对不是一个好主意。
黑客仍然可以逃脱 XSS 吗?
可能,视情况而定。
@BenoitEsnard 已经描述了一种过滤但<还>不够的情况:当用户输入在现有 HTML 标记的属性内回显时,因为攻击者可以自己添加新属性。
这是一个包含不同上下文的列表,以及在防止 XSS时如何处理它们。
有什么理由不这样做吗?
是的。
假设您实际上只<textarea>COMMENT</textarea>在编辑评论时在内部回显评论,<div id=comment>COMMENT</div>在显示评论时在内部回显,在其他任何地方都没有,并且您根本不需要任何 HTML 格式,只是您所说的纯文本。
如果您正确编写函数,它将是安全的。但它不会对用户非常友好。根据您拥有的网站类型,用户可能希望在许多情况下使用,例如:<, , , , , ...>Love you <32 < 3use this: this->exec()<font> is deprecated>.<
所以这绝对是一个可用性问题,并且可能是一个安全问题,具体取决于上下文和实现的正确性。
只需使用常用的函数而不是编写自己的机制(例如,在 PHP中,在您不想解析给定 HTML 的 HTML 上下文中回显用户输入时使用htmlentities ,如果您确实需要 HTML,请使用一些库,例如HTMLPurifier ,等等)
不,这还不够——如果你只是盲目地将用户提交的文本插入到 HTML 输出中,那么在许多不同的上下文中,其他符号可以被视为标记的一部分。最安全且可以说是正确的方法是明确地将纯文本视为纯文本。使用来自服务器的基于 JavaScript 的单独请求检索此文本,或者作为文本块或打包在 JSON 中,并将其直接分配给dataDOM 中文本节点的属性。这样,您就可以保证它不会被处理为任何东西,而只是纯文本,而不会妨碍用户使用他们想要的任何符号的能力。
// Obtain user somehow generated text. For this demonstration I'll just inline it.
var text = "some <funky> &text& with something that looks like </script> suspicious HTML"
// Find target text node in your page. For this demonstration I'll just create it myself.
var text_node = document.createTextNode('')
document.body.appendChild(text_node)
// Now just assign your text data to node
text_node.data = text