不受信任的值如何作为 javascript 字符串常量包含在 html 页面中?虽然我问的案例使用 JSF 和 Rails,但我认为这是一个独立于服务器端框架的一般问题。
属性
在 on-attributes 中逃避 \'" 显然是不够的:
onclick='alert("[variable]")'
variable: hello, world"); alert("XSS
result: alert("hello, world"); alert("XSS")
在 Firefox 中,这将显示一个“hello, world”和一个“XSS”警报对话框。由于变量不包含 ",Rails 函数escape_javascript在这种情况下是不够的。应用 html 转义似乎是安全的,因为在这种情况下只显示原始对话框:
result: onlick='alert("hello, world"); alert("XSS")'
脚本标签
然而,在 <script> 标签中,Firefox 应用了不同的规则:
<script type="text/javascript">
alert("hello, world"); alert("XSS");
</script>
这只会显示一个对话框;但引号以转义形式显示。有两个结论:1)" 不被解析为 JavaScript 引号(好),2)它也没有根据 HTML 规则解析(坏)。因此,任何对 html 转义常量的尝试都会创建损坏的数据。
但是,跳过脚本标签中的 html 转义不是一种选择:
<script type="text/javascript">alert("[variable]");</script>
variable: hello, world</script><script>alert("XSS
result: <script type="text/javascript">
alert("hello, world</script><script>alert("XSS");</script>
由于缺少 ",第一个脚本标签会产生语法错误。但在 Firefox 中,会执行注入的第二个脚本标签。
tl,博士
是否有一种安全的方法可以将不受信任的值写入 JavaScript 常量?这似乎是一团糟,我目前倾向于使用 html 元素(使用 style="dispaly:none")来代替。使用 JSON 的 XMLHttpRequest 调用将是另一种选择。但这两种方法都感觉像是在作弊。