64

如何使用 DOM XSS 来绕过 CSP 的 nonces 机制(半机翻有删增)

 5 years ago
source link: https://www.k0rz3n.com/2019/03/09/如何使用 DOM XSS 来绕过 CSP 的 nonces 机制(半机翻有删增)/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

CSP nonces 在对抗 DOM XSS 方面似乎并没有所谓的奇效。你可以通过几种方法绕过它们。我不知道如何修复,也许不应该修复。

谢谢你的阅读。这篇博文讲述了CSP nonces 的绕过方法,从一些背景开始,接着介绍在几种情况下如何绕过CSP nonces,并以一些评论结束。和往常一样,这篇博文是我对这个主题的个人看法,我很想听听你的看法。

0X01 我与CSP的关系,”错综复杂”

我以前喜欢Content-Security-Policy。大约在2009年,我曾经非常兴奋。我的兴奋程度很高,我甚至花了很多时间在我的ACS项目中用JavaScript实现CSP(据我所知,这是第一个正在运行的CSP实现/原型)。 它支持哈希和白名单 ,我真的相信它会很棒!

但有一天,我的一位来自elhacker.net(WHK)的朋友指出 ,使用JSONP可以简单地规避ACS(以及扩展的CSP) 。 他指出, 如果你将包含JSONP端点的主机名列入白名单,那么安全机制就会被破坏 ,确实有很多这样的情况,以至于我没有看到解决这个问题的简单方法,我的心碎了

快进到2015年,Mario Heiderich做了一个很酷的XSS挑战,名为“ Sh*t,it’s CSP! ”,其中的挑战是以最短的有效载荷逃离一个看似安全的CSP。不出所料,JSONP出现了(但也是Angular和Flash)。

然后在2016年终于有一篇名为“CSP Is Dead,Long Live CSP!”的相当受欢迎的论文。在完成了由Miki,Lukas,Sebastian和Artur执行的CSP部署的互联网范围调查之后,WHK和Mario强调了问题。该论文的结论是CSP白名单完全被破坏和无用。我想,至少CSP参加了葬礼。

然而,并没有那么简单。作为贡献,该论文主张使用CSP nonces 而不是原始的基于白名单的策略,这是CSP新方式的美好未来!

当首次提出CSP nonces时,我对它们的关注是它们的权限传递似乎非常困难。为了解决这个问题, 2012年的 dominatrixss-csp 使得所有动态生成的脚本节点都可以通过使用动态资源过滤器传递脚本的nonces来工作 。这使得nonces 的传递非常简单。因此,本文提出了这种确切的方法,并命名为 strict-dynamic,现在支持用户代理,而不是像dominatrixss-csp那样的运行时脚本。很大的改进。我们得到了一个本地的dominatrixss!

这种新的CSP风格, 建议完全忽略白名单,并完全依赖于nonces 。虽然CSP nonces的部署比白名单更难(因为它需要在策略的每一页上进行服务器端更改),但它似乎提出了真正的安全性好处,这显然缺乏基于白名单的方法。再一次,今年秋天,我对这种新方法相当乐观。也许有一种方法可以让大多数XSS实际上真的不可触发。也许CSP毕竟不是假的!

但是这个圣诞节,如果它是来自圣诞老人的一块煤,塞巴斯蒂安莱基斯指出,在我看来,似乎是对CSP nonces的重大打击,几乎完全使CSP对2016年的许多XSS漏洞无效。

0X02 一个 CSS + CSP + DOM XSS three-way

虽然CSP nonces确实看起来能够抵御15年前的XSS漏洞, 但它们似乎对DOM XSS没那么有效 。为了解释原因,我需要向您展示如今的Web应用程序是如何编写,以及它与2002年的不同之处。

以前,大多数应用程序逻辑都存在于服务器中,但在过去的十年中,它一直在向客户端移动。 现在有一天,开发Web应用程序的最有效方法是在HTML + JavaScript中编写大部分UI代码 。除了其他方面, 这允许使Web应用程序脱机就绪,并提供对无限供应的强大Web API的访问。

而现在,新开发的应用程序仍然具有XSS,不同之处在于, 由于很多代码都是用JavaScript动态生成的现在它们都有DOM XSS 。而这些正是CSP nonces无法持续防御的错误类型(至少目前已实施)。

让我举三个例子(当然是非详尽的列表)DOM XSS漏洞是常见的,单独的CSP nonces无法防御:

(1)当攻击者可以强制定向到易受攻击的页面时并且有效 payload 不包含在缓存的响应中(因此需要获取) 时会出现 存储型 DOM XSS:

(2)在页面包含第三方HTML代码的地方,例如,

fetch(location.pathName).then(r=>r.text()).then(t=>body.innerHTML=t);

会出现 DOM XSS 漏洞

(3)XSS有效负载位于location.hash中,例如,

https://victim/xss#!foo?payload=

的地方会出现 DOM XSS 漏洞

为了解释原因,我们需要回到2008年(woooosh!)。早在2008年,Gareth Heyes,David Lindsay和我在Microsoft Bluehat上做了一个小小的演讲,名为 CSS-The Sexy Assassin 。除此之外,我们还展示了一种纯粹使用CSS3选择器读取HTML属性的技术(几个月之后,它被WiSec重新发现并在其25c3谈话 Attacking Rich Internet Applications 与kuza55 一起呈现)。

这种攻击的总结是,可以创建一个CSS程序,逐个字符地展示HTML属性的值,只需每次CSS选择器匹配时生成HTTP请求,然后连续重复。如果您还没有看到这个工作,请看看这里。它的工作方式非常简单,它只是创建一个表单的CSS属性选择器:

*[attribute^="a"]{background:url("record?match=a")}
*[attribute^="b"]{background:url("record?match=b")}
*[attribute^="c"]{background:url("record?match=c")}
[...]

然后,一旦我们得到一个匹配,重复:

*[attribute^="aa"]{background:url("record?match=aa")}
*[attribute^="ab"]{background:url("record?match=ab")}
*[attribute^="ac"]{background:url("record?match=ac")}
[...]

直到它渗透完整的属性。

对脚本标记的攻击非常简单。我们需要进行完全相同的攻击,唯一需要注意的是确保脚本标记设置为display:block;

因此, 我们现在可以使用CSS提取CSP随机数 ,我们唯一需要做的就是能够在同一个文档中多次注入。上面给出的DOM XSS的三个例子恰好就是这样。一种在同一文档中多次注入XSS有效 payload 的方法。完美的 three-way。

0X03 概念验证

好的!让我们这样做=)

首先,存储型的DOM XSS这个问题尤其令人不安,因为如果在“新世界”中,开发人员应该用JavaScript编写UI,那么动态内容需要异步地来自服务器。

我的意思是,如果用HTML + JavaScript编写UI代码,那么用户数据必须来自服务器。虽然此设计模式允许您控制应用程序逐步加载的方式,但它也使得加载同一文档两次可以每次返回不同的数据。

当然,现在的问题是: 如何强制文档加载两次!?当然,使用HTTP缓存! 这正是塞巴斯蒂安今年圣诞节向我们展示的。

Sebastian解释了CSP nonces 如何与大多数缓存机制不兼容,并提供了一个简单的概念证明来 证明它 。经过一些关于Twitter的讨论后,后果变得非常清楚,以一种冷酷可怕的方式

让我向您展示一个示例,让我们从 AppEngine入门指南 中获取默认的Guestbook示例,并进行 添加一些 AJAX支持和CSP nonces的修改。应用程序很简单,容易受到 明显的XSS攻击 ,但它可以 通过CSP nonces来缓解 ,真的是这样吗

这里的 iframe 由于无法引入,故请读者去看原文

上面的应用程序有一个非常简单的存储型 XSS。只需提交XSS有效负载(例如, <H1> XSS </ H1> ),您就会明白我的意思。但是虽然那里有一个XSS,但由于CSP的现状,你实际上无法执行JavaScript。

现在,让我们进行攻击,回顾一下,我们将:

1.使用CSS属性读取器窃取CSP随机数。

2.使用CSP随机数注入XSS有效内容。

窃取CSP 随机数实际上需要一些服务器端代码来跟踪强制执行。您可以在 此处 找到代码,然后单击上面的按钮即可运行代码。

如果一切正常,单击“注入XSS有效负载”后,您应该已收到 alert。不是很好吗?。在这种情况下,我们使用的缓存是 BFCache ,因为它是最可靠的,但你可以像Sebastian在 他的PoC 中那样使用传统的HTTP缓存。

0X04 其他的 DOM XSS

存储型性 DOM XSS并不是CSP nonces中唯一的弱点。塞巴斯蒂安在 postMessage 上展示了同样的问题。另一个也存在问题的端点是XSS到HTTP “inclusio”。这是一个相当常见的XSS漏洞,它 只是提取一些用户提供的URL并在innerHTML中回显它 。这相当于JavaScript的远程文件包含。该漏洞与其他漏洞完全相同。

最后,今天的最后一个PoC是location.hash,它也很常见。也许原因是因为IE的怪癖,但许多网站必须使用位置哈希来在单页JavaScript客户端中实现历史和导航。它甚至有一个绰号” hashbang “。事实上,这是非常普遍的,每个使用jQuery Mobile的网站都默认启用这个”特性”,无论他们喜欢与否。

从本质上讲,任何使用hashbang进行内部导航的网站都容易受到反射XSS的影响,就好像CSP nonces不存在一样。那太疯狂了!在 这里 查看PoC(仅限Chrome浏览器 - Firefox转义位置.hash)。

0X05 结论

哇,这是一篇很长的博文…但至少我希望你发现它很有用,希望现在你能够更好地理解CSP的真正有效性,也许可以学习一些浏览器技巧,并希望得到一些想法用于未来的研究。

  • CSP是否可以防止一些漏洞?应该是!我认为GOBBLES在2002年报告的所有错误都应该可以通过CSP nonces来预防。
  • CSP是灵丹妙药吗?不,绝对不是。它的覆盖范围和有效性比我们(或至少我)最初认为的更脆弱。

我们将何去何从?

1.我们可以尝试在运行时锁定CSP,正如Devdatta所提出的那样。

2.我们可以禁止CSS3属性选择器来读取nonce属性。

3.我们可以放弃CSP。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK