将 `<` 转换为 `<` 是否足以防止从任意 HTML 执行 JavaScript?

信息安全 xss javascript html
2021-08-24 07:53:02

这是一个赌注的问题。我的一个熟人声称,给定一个任意的 HTML 全局,如果在将其放入网页之前,将所有实例替换为 -- 并且不进行其他更改,则可以完全阻止执行 JavaScript 。<&lt;

我不相信我的熟人是正确的,但我也想不出反例。任何人都可以证明或反驳吗?

澄清:假设转义发生在服务器端,并且 glob 作为普通元素的内容插入,例如

<p>{{ GLOB GOES HERE }}</p>

此外,假设客户端正确地实现了 HTML5 解析器算法;我们不担心错误、遗留解析器或仅适用于 XML 或 SGML 的场景。

进一步澄清:OWASP 规则是故意保守的。因为这是赌注,所以我们想要一个迂腐的答案,而不是保守的答案。

4个回答

在元素内部,解析模式处于数据状态。唯一可以转义数据状态的特殊字符是<&https://html.spec.whatwg.org/multipage/parsing.html#data-state sec.13.2.5.1)。

如果您替换所有实例,<那么&lt;您只需要担心&.

在 HTML4 和 XML 中,您需要考虑哪些实体引用可用于替换,以及它们中的任何一个是否可用于注入脚本或其他攻击媒介。这可能是一个问题,例如,如果标记引用外部 DTD 并且攻击者可以将外部 DTD 的网络下载重定向到他们自己选择的一个。这是许多 XML 和 HTML 解析器不通过网络解析系统标识符的原因之一。

但是,HTML5 只允许&用于字符实体,不能用于转义数据模式。

因此,在解析器标记中没有错误的情况下,您的认识是正确的。

这取决于在 HTML 文档中打印数据的位置,因为在不同的规则中有不同的上下文仅当<是一个特殊字符时,替换文字才可行,这会改变当前的解析状态。&lt;<

在 OWASP 的XSS(跨站点脚本)预防备忘单中有一个预防规则的快速概述,它应该给你一些你应该注意的提示。

取决于很多因素。

如果恶意输入(默认情况下所有用户的输入都是恶意的)仅回显到您的 HTML 正文并且您的服务器发送标头“Content-Type: text/html; charset=utf-8”和“X-Content-Type-Options :nosniff”,答案是肯定的,这种方法足够安全。

当我说 HTML 正文时,我假设您正在将输入回显到 <html><body>INPUT_HERE</body></html>.

如果您只是将输入回显到空白页面,在输入之前没有几个字节,则可以使用 Rosetta Flash 攻击。

这是非常糟糕的做法。你保留了一个黑名单。但推荐的方法是保留一个白名单,在过滤后只给出允许的字符。

您的问题的答案是,<可以进行十六进制编码并以其他编码方案编写。因此,简单地替换<&lt;是不够的。