利用X-XSS-Protection进行恶意攻击的技术解析

本文深入探讨了X-XSS-Protection头的不同配置如何影响XSS防护效果,通过实际代码演示攻击者如何利用未启用block模式的配置绕过防护,并对比了Content-Security-Policy的防护机制。

如何利用X-XSS-Protection进行恶意攻击

2018年2月10日

两个可以缓解XSS攻击的重要响应头是:

  • X-XSS-Protection
  • Content-Security-Policy

那么它们有什么区别呢?

像Internet Explorer和Chrome这样的浏览器包含一个"XSS审计器",它试图帮助防止反射型XSS攻击触发。第一个响应头控制浏览器内的这个功能。

详细说明在这里,但基本上支持的四个选项是:

  • X-XSS-Protection: 0
  • X-XSS-Protection: 1
  • X-XSS-Protection: 1; mode=block
  • X-XSS-Protection: 1; report=

需要注意的是,除非用户(或其管理员)禁用了它,否则审计器默认是激活的。

因此,X-XSS-Protection: 1将为用户重新启用它。

第二个响应头Content Security Policy是一个较新的头部,它控制HTML页面可以从哪里加载内容,包括JavaScript。基本上,除了unsafe-inline之外的任何指令都意味着注入到页面中的JavaScript将不会执行,并且可以缓解反射型和存储型XSS攻击。CSP是一个比我在这里要涵盖的更广泛的话题,但是关于该头部的详细信息可以在这里找到。

我想向你展示的是指定block模式与完全不包含该头部(因此将采用浏览器中的设置)或指定1而不带block模式之间的区别。此外,为了更好的说明,我还将展示Content Security Policy对跨站脚本攻击的缓解措施。

我将向你展示一种方法,如果站点指定了X-XSS-Protection但没有使用block模式,如何滥用这一点。

链接页面包含以下代码:

1
2
3
<script>document.write("one potato")</script><br />
<script>document.write("two potato")</script><br />
three potato

如果我们直接从你正在阅读的当前页面链接到那里,两个脚本块应该会触发:

正常链接

为了演示XSS审计器的工作原理,让我们想象我们尝试通过附加以下查询字符串来注入该脚本到页面中:

1
?xss1=<script>document.write("one potato")</script>&xss2=<script>document.write("two potato")</script>

请注意,以下内容在Firefox中不起作用,因为在撰写本文时,Firefox不包含任何XSS审计器,因此如果访问的站点存在漏洞,它很容易受到反射型XSS攻击。如果Firefox是你选择的浏览器,你可以使用noscript附加组件来保护自己。请注意,以下内容仅在Chrome 64中进行了测试。我还将通过向输出添加X-XSS-Protection: 1来在支持的浏览器中启用你的XSS过滤器。

注入链接

请注意浏览器现在如何认为两个脚本块已被注入,因此阻止它们并仅输出纯HTML。如果你不相信代码仍然存在,请查看源代码。

查看F12开发者工具显示审计器已完成其工作:

查看源代码显示哪个脚本已被阻止(红色显示):

攻击者如何滥用XSS审计器?他们可以操纵页面以阻止他们选择的脚本。

1
?xss2=<script>document.write("two potato")</script>

被滥用的链接

查看源代码显示攻击者通过在URL中指定源代码来阻止了他们想要的内容:

当然,编辑他们自己的链接是徒劳的,他们必须通过电子邮件、Facebook、Skype等方式将链接传递给受害者。

这有什么风险?《Web应用程序黑客手册》说得比我好:

那么,我们如何防御这一点?嗯,你猜对了,就是block指令:

1
X-XSS-Protection: 1; mode=block

让我们用这个指定再试一次:

启用block模式的被滥用链接

因此,通过指定block,我们可以防止攻击者制作链接来中和我们现有的脚本!

总之,最好总是指定block模式,因为默认情况下XSS审计器只尝试阻止它们认为被注入的内容,这可能实际上并不是恶意脚本本身。

那么Content Security Policy呢?

只是为了演示区别,如果我们输出一个阻止内联脚本的CSP头部,并且不尝试注入任何内容:

CSP示例

Chrome向我们显示这完全是由于Content Security Policy:

作为站点开发者,我们可以通过在CSP中指定SHA-256哈希,或者简单地将代码移动到单独的.js文件中(只要我们在策略中白名单self)来绕过这一点。任何注入内联脚本的攻击者都将被阻止。当然,Content Security Policy的问题在于,它似乎仍然是一个事后想法,并且尝试制定一个适合现有站点的策略非常困难,除非你的站点几乎是静态的。然而,如果做得正确,它是一个很好的缓解措施。不过,策略中的任何弱点都可能被利用。希望如果我将来在任何项目中遇到它,我会有一篇关于这个的文章。

*是的,你不是在使用X-XSS-Protection进行恶意攻击,但当然缺乏block模式,如果没有人弄乱浏览器设置,就好像已经输出了X-XSS-Protection: 1。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计