CSP 概念及绕过分析总结

 

有关CSP的指令意思以及其值的含义,在这里已经写得很清楚了,下面我罗列并翻译一下关键的信息。

CSP 概念

指令参考

一个CSP 值可以包含一个至多个指令,通过;间隔。下面简单介绍一下各个指令含义:

Directive Example Value Description
default-src 'self' cdn.example.com 定义资源默认加载策略
script-src 'self' js.example.com 定义 JS 加载策略
style-src 'self' css.example.com 定义 CSS 加载策略
img-src 'self' img.example.com 定义图片加载策略
connect-src 'self' 定义 Ajax、WebSocket 等加载策略
font-src font.example.com 定义 Font 加载策略
object-src 'self' 定义 等引用资源加载策略
media-src media.example.com 定义
frame-src 'self' 定义 Frame 加载策略
sandbox allow-forms allow-scripts 对页面的操作应用限制,包括阻止弹出窗口,阻止插件和脚本的执行以及强制执行同源策略。可以不设置sanbox的值使得所有限制启用,或者手动启用以下属性 : allow-forms allow-same-origin allow-scripts allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to-escape-sandbox, and allow-top-navigation
report-uri /some-report-uri 指定浏览器报告策略错误的URL,可以在HTTP头中添加-Report-Only 来指示浏览器只报告不阻断
child-src 'self' child-src指令管理了套嵌浏览的部分(类似于iframe、frame标签)
form-action 'self' 定义了form表单中action的范围
frame-ancestors 'none' 定义<frame> <iframe> <object> <embed> <applet>加载策略. 直接设置‘none’ 几乎等于设置了X-Frame-Options: DENY
plugin-types application/pdf 设置有效的MIME类型

 

指令取值

Source Value Example Description
* img-src * 通配符,允许所有的URL
'none' object-src 'none' 拒绝从任何地址加载资源
'self' script-src 'self' 允许同源加载
data: img-src 'self' data: 允许使用data协议加载资源,如加载base64格式图片
domain.example.com img-src domain.example.com 允许从特定域名加载资源
*.example.com img-src *.example.com 仅允许该域名的子域名加载资源
https://cdn.com img-src https://cdn.com 仅允许HTTPS且域名相配的地址加载资源
https: img-src https: 仅允许从HTTPS加载资源
'unsafe-inline' script-src 'unsafe-inline' 允许使用内联资源,比如内敛CSS、JS等(Allows use of inline source elements such as style attribute, onclick, or script tag bodies (depends on the context of the source it is applied to) and javascript: URIs)
'unsafe-eval' script-src 'unsafe-eval' 允许JS的动态执行命令eval()
'nonce-' script-src 'nonce-2726c7f26c' 如果nonce值设置正确,允许scriptstyle 标签执行代码,如: <script nonce="2726c7f26c">alert("hello");</script>
'sha256-' script-src 'sha256-qzn*...*ng=' r如果hash匹配,允许执行指定script和style代码。如: sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng= will allow alert('Hello, world.');

 

以下为上面指令可以取的值,多个值可以用空格间隔,若为'none'则只能有一个值。

小例子

Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';

这个例子意味着允许加载同源的JS脚本、CSS、AJAX(or WebSocket)、拒绝加载其他任何的资源。

Bypass CSP

unsafe-inline

在真实的开发环境中,由于网站开发维护周期长,开发人员多,常常不得已需要执行内联script,这样就给我们留下了漏洞,只要存在XSS漏洞,我们就可以借此执行内联Js。

如果connect-src: self 设定了话,就无法向其他域名发送数据,但我们可以通过寻找站内可以api,如上传文件、发布文章等处导出数据。

预加载

一般来说,self代表只接受符合同源策略的url,这样一来,大部分的xss和crsf都会失效。但link标签除外。我们可以通过link标签绕过CSP

<link rel="prefetch" herf="xxxxxxx"> (经测试,火狐、chrome均失效)

DNS预解析:

<link rel="dns-prefetch" href="xxxxxxxx"> (经测试,仍然可以绕过Chrome,火狐最新版无效)

这样,我们可以通过预加载,将数据添加到link请求的链接中,或者dns预解析的子域名中,从DNS记录中拿到数据。

通过iframe标签绕过script-src

sandbox 中的allow-popups开启时,window.open就可以打开新的窗口。

frame-src如果为self,iframe的src必须为为同源,如果我们指向任意一个没有csp的同源文件,此时我们可以在iframe中引入js,此时因为iframe打开的这个页面没有csp限制,其中的js就可以任意执行了。

假如对应站点,任何预期站点响应都包含X-Frame-Options: Deny ,我们可以通过以下方法绕过:

  1. 使用不存在的网页,大部分网页404报错不会包含X-Frame-Options: Deny
  2. frame.src=”/”+”A”.repeat(20000); 通过url过长触发错误(测试未成功)

    3. cookie过长触发报错

WebRTC 绕过 connect-src

我们知道,如果设置了connect-src这意味着即使可以执行内联js,我们仍然无法向外界通过AJAX或者WebSocket带出数据。但是此时,我们可以使用WebRTC绕过。

这个姿势是在今年的RCTF学到的,我也写了这道题的WP,有兴趣可以看看。

参考链接

https://www.anquanke.com/post/id/84853

https://content-security-policy.com/

https://lorexxar.cn/2016/08/08/ccsp/

https://www.cnblogs.com/afanti/p/9298415.html

https://news.ycombinator.com/item?id=17512005

https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa

https://twitter.com/i_bo0om/status/1016422138285355014

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注