HTML Encoding 会阻止各种 XSS 攻击吗?
Posted
技术标签:
【中文标题】HTML Encoding 会阻止各种 XSS 攻击吗?【英文标题】:Will HTML Encoding prevent all kinds of XSS attacks? 【发布时间】:2010-09-08 09:33:41 【问题描述】:我不关心其他类型的攻击。只是想知道html Encode是否可以防止各种XSS攻击。
即使使用 HTML 编码,有没有办法进行 XSS 攻击?
【问题讨论】:
【参考方案1】:没有。
撇开允许一些标签的主题(不是问题的重点),HtmlEncode 根本不涵盖所有 XSS 攻击。
例如,考虑服务器生成的客户端 javascript - 服务器将 htmlencoded 值直接动态输出到客户端 javascript,htmlencode 将不会停止注入的脚本执行。
接下来,考虑下面的伪代码:
<input value=<%= HtmlEncode(somevar) %> id=textbox>
现在,如果它不是很明显,如果 somevar(当然是由用户发送的)设置为例如
a onclick=alert(document.cookie)
结果输出是
<input value=a onclick=alert(document.cookie) id=textbox>
这显然会起作用。显然,这可以是(几乎)任何其他脚本......而 HtmlEncode 没有多大帮助。
还有一些额外的向量需要考虑...包括第三种类型的 XSS,称为基于 DOM 的 XSS(其中恶意脚本是在客户端动态生成的,例如基于 # 值)。
也不要忘记 UTF-7 类型的攻击 - 攻击的样子
+ADw-script+AD4-alert(document.cookie)+ADw-/script+AD4-
那里没什么可编码的......
当然,解决方案(除了适当和限制性的白名单输入验证之外)是执行context-sensitive编码:如果您的输出上下文是 HTML,则 HtmlEncoding 非常棒,或者也许你需要 JavaScriptEncoding,或者 VBScriptEncoding,或者 AttributeValueEncoding,或者……等等。
如果您使用的是 MS ASP.NET,则可以使用他们的 Anti-XSS 库,它提供了所有必要的上下文编码方法。
请注意,所有编码不应仅限于用户输入,还应包括来自数据库、文本文件等的存储值。
哦,别忘了在 HTTP 标头和 META 标记中显式设置字符集,否则您仍然会有 UTF-7 漏洞...
更多信息和非常明确的列表(不断更新),请查看 RSnake 的备忘单:http://ha.ckers.org/xss.html
【讨论】:
首先当然是错误的写成 id=textbox> 而不是 id=textbox> 如果您不知道 tekst 是否包含例如一个空白。 这正是重点——HTMLEncode 不能保护您免受错误的影响。当然,程序员希望 somevar 包含 23 - 正是那个讨厌的攻击者决定在里面塞一个空白...... Espo - 我迟到了这个游戏 - 但它肯定有助于封装和编码 - 在你的例子中,htmlencoding它(引用)将产生:"因此将是 onclick="alert() @Adam,这里正确的解决方案是attribute-encode它(除了封闭它),而不是html-encode。上下文不同,因此编码规则也不同 - html 编码在这里对您没有帮助。 @AviD 给定一个确实对引号字符进行编码的 HtmlEncode() 函数(如示例中的 ASP 代码那样),您能否提供一个用于 @ 的 XSS 值示例987654326@?【参考方案2】:如果您在显示之前系统地编码所有用户输入那么是的,您是安全的您仍然不是 100% 安全。
(更多详情请查看@Avid 的帖子)
此外,当您需要让一些标签未编码时会出现问题,以便您允许用户发布图像或粗体文本或任何需要将用户输入处理为(或转换为)un的功能-编码标记。
你必须建立一个决策系统来决定哪些标签是允许的,哪些是不允许的,而且总是有可能有人会想办法让一个不允许的标签通过。
如果您在输出未处理的用户数据(静态类型)时遵循 Joel 的 Making Wrong Code Look Wrong 或 your language helps you 的建议,通过警告/不编译会有所帮助。
【讨论】:
虽然这包括绕过某些标签的一个好点,但问题的答案是错误的。看我的回答... 向 OP 添加了评论,以便他接受您的回答。并在我的帖子中添加了一个链接到您的答案,以防万一。【参考方案3】:如果您对所有内容进行编码,它会。 (取决于您的平台和 htmlencode 的实现)但是任何有用的 Web 应用程序都非常复杂,以至于很容易忘记检查它的每个部分。或者,第 3 方组件可能不安全。或者,也许您虽然进行了编码的某些代码路径没有这样做,所以您在其他地方忘记了它。
因此,您可能还想检查输入端的内容。您可能想检查从数据库中读取的内容。
【讨论】:
【参考方案4】:正如其他人所提到的,只要在显示之前对所有用户输入进行编码,您就安全了。这包括从数据库中检索到的所有请求参数和可通过用户输入更改的数据。
作为mentioned by Pat,您有时会想要显示一些标签,而不是所有标签。一种常见的方法是使用Textile、Markdown 或BBCode 之类的标记语言。但是,即使是标记语言也容易受到 XSS 的攻击,请注意。
# Markup example
[foo](javascript:alert\('bar'\);)
如果您确实决定让“安全”标签通过,我建议您在输出之前找到一些现有的库来解析和清理您的代码。在您的消毒剂相当安全之前,您必须先检测到 a lot of XSS vectors。
【讨论】:
【参考方案5】:我赞同 metavida 的建议,即寻找第三方库来处理输出过滤。中和 HTML 字符是阻止 XSS 攻击的好方法。但是,用于转换元字符的代码可能容易受到规避攻击;例如,如果它不能正确处理 Unicode 和国际化。
自制输出过滤器犯的一个典型的简单错误是只捕获 ,但错过了诸如“”之类的内容,这可能会将用户控制的输出破坏到 HTML 标记的属性空间中,其中 Javascript 可以附加到 DOM .
【讨论】:
【参考方案6】:不,仅编码常见的 HTML 令牌并不能完全保护您的网站免受 XSS 攻击。例如,请参阅在 google.com 中发现的这个 XSS 漏洞:
http://www.securiteam.com/securitynews/6Z00L0AEUE.html
此类漏洞的重要之处在于,攻击者能够使用 UTF-7 对其 XSS 负载进行编码,并且如果您没有在页面上指定不同的字符编码,用户的浏览器可能会解释 UTF- 7 payload并执行攻击脚本。
【讨论】:
【参考方案7】:您需要检查的另一件事是您的输入来自哪里。您可以使用引荐来源字符串(大部分时间)来检查它是否来自您自己的页面,但是在您的表单中输入一个隐藏的随机数或其他内容,然后检查它(可能使用会话集变量)也有助于了解输入来自您自己的网站,而不是某个钓鱼网站。
【讨论】:
【参考方案8】:我想推荐 HTML Purifier (http://htmlpurifier.org/) 它不只是过滤 html,它基本上标记化并重新编译它。它是真正的工业实力。
它还有一个额外的好处是允许您确保有效的 html/xhtml 输出。
同样是纺织品,它是一个很棒的工具,我一直都在使用它,但我也会通过 html 净化器来运行它。
我认为你不明白我的意思是重新标记。 HTML Purifier 不只是“过滤”,它实际上重构了 html。 http://htmlpurifier.org/comparison.html
【讨论】:
【参考方案9】:我不相信。 Html Encode 将所有功能字符(可以被浏览器解释为代码的字符)转换为无法被浏览器解析并因此无法执行的实体引用。
<script/>
浏览器无法执行上述操作。
**当然,除非它们是浏览器中的错误。*
【讨论】:
或者,如果 Javascript 以某种方式被用于更改用户输入以实现 GUI 目的。我遇到了一个 XSS 漏洞,起初将 编码为 ... 但是当传递给这个函数时,它们又被替换了!所以……我猜你的 XSS 预防措施已经完成了。 :)【参考方案10】:myString.replace(/]*>?/gm, '');
我使用它,然后成功。 Strip HTML from Text JavaScript
【讨论】:
以上是关于HTML Encoding 会阻止各种 XSS 攻击吗?的主要内容,如果未能解决你的问题,请参考以下文章