CSP 学习记录

0x00 CSP 是什么

Content Security Policy (CSP)内容安全策略,是一个附加的安全层,有助于检测并缓解某些类型的攻击,包括跨站脚本(XSS)和数据注入攻击。
CSP的特点就是他是在浏览器层面做的防护,是和同源策略同一级别,除非浏览器本身出现漏洞,否则不可能从机制上绕过。
CSP只允许被认可的JS块、JS文件、CSS等解析,只允许向指定的域发起请求。
总结来说,CSP就是浏览器层面的,通过对不同类型的资源的来源、方式做限制来控制资源的加载,从而达到防止某些漏洞产生的策略。

0x01 内容源

内容源是用来声明资源可能从哪里加载的字符串
其形式包括
* 允许任意url加载但是不能够使用data:blob:filesystem:schemes协议
http://*.xxxx.com 用于匹配所有使用http协议加载foo.com任何子域名的尝试
xxx.xxx.com:123 匹配所有访问域名端口的尝试
https:// 匹配所有使用https协议访问的尝试

除此之外,还有一些关键字可以用来描述一些特别的内容源,比如
'none' 表示不匹配任何url
'self' 代表只允许同源内容
'unsafe-inline' 代表允许使用内联资源,比如页面内的js脚本内容加载
'unsafe-eval' 表示允许使用eval()等通过字符串创建代码的方法
data: 代表允许data:协议URI作为内容来源
mediastream: 允许mediastream:协议URI作为内容源
nonce值 每次HTTP回应给出一个授权token,页面内嵌脚本必须有这个token,才会执行。类似'nonce=xxxxx'
hash值 列出允许执行的脚本代码的Hash值,页面内嵌脚本的哈希值只有吻合的情况下,才能执行,类似'sha-256 xxxxxxx',页面内脚本内容hash值吻合的情况下才能执行
strict-dynamic 允许合规的js动态添加js脚本,一种信任传递

0x02 策略指令

策略指令是用于描述策略限制的范围
base-uri :定义了 URI,它可以作为文档的基准 URL。如果没有指定值,那么任何 URI 都被允许。如果没有指定这条指令,浏览器会使用 base 元素中的 URL
child-src :定义了 web workers 以及嵌套的浏览上下文(如 <frame> 和 <iframe> )的源。推荐使用该指令,而不是被废弃的 frame-src 指令。对于 web workers,不符合要求的请求会被当做致命网络错误。
connect-src :定义ajax、websocketh和eventsource等加载策略
default-src :定义资源默认加载策略,其中如果(child-src、connect-src、font-src、img-src、media-src、object-src、script-src、style-src)没有指定的话,都由default来指定
font-src :定义@font-face加载策略
form-action :指定了from提交的加载策略
frame-ancestors :该指令制定可以使用<frame>和<iframe>元素嵌入页面的有效父项。 但此指令在元素对象中或在Content-Security-policy-Report-Only标题字段中不被支持。
frame-src :定义frame加载策略
img-src :定义图片加载策略
meida-src :定义<audio><video>等媒体资源加载策略
object-src :定义<embed><object>等对象引用资源加载策略
referer :指定referer发送策略
reflected-xss :在meta头中会失效,该指令告诉浏览器开启或关闭任何用于过滤或阻止反射跨站脚本攻击的启发式算法,这相当于X-XSSProtection 响应头的效果
report-uri :定义是否提交日志
sandbox :该指令指定对页面的哪些操作加以限制
script-src :定义js加载策略
style-src :定义css加载策略

0x03 bypass技巧

#在开启了页面缓存,页面存在任意XSS的情况下,可以同构构造两个同源的iframe,一个iframe构造截断或者其他内容取得nonce部分数据并发送出去,一个iframe构造接收使用nonce构造payload的情况。
#在xx-src情况下,可以通过<link rel="prefetch" href="http://xxxxxxx.cn"> (H5预加载)(only chrome)
<link rel="dns-prefetch" href="http://xxxxxxxx.cn"> (DNS预加载)以及prefetch、preconnect、prerender来绕过限制(浏览器种类和版本限制,本地复现均失败。)
#可以上传文件写入js的情况下,构造来引入js执行,但在浏览器解析过程中需要有格式限制或者其他绕过MIME的方法
#在有允许的default-src=xxxxcdn的情况下,可以尝试使用cdn的api来构造payload
#在限制路径的情况下,目录中有跳转可以跳转到可控JS内容来引入脚本
#在一些框架中,可能存在框架自带的某些特点可以完全绕过CPS,例如angular的某些标签
#存在jsonp获取数据且未做好完善过滤的情况下,jsonp的域肯定是可信域,可以构造jsonp的callback部分
#unsafe-inline,可以内联脚本,还可以通过页面内js脚本构造link prefetch发送跨域请求,构造带href属性的一些标签标签本身也可以做到差不多的效果
#合法的跨域行为,包括构造js跳转和带href的跨域请求。说到这里,href和src的区别,src为替换资源,而href用于建立与其他资源的关系。
#302跳转的问题,针对资源目录限制的情况,bypass可以用302跳转实现,在允许的域下存在可以跳转的页面,使用跳转可以bypass目录的限制,但是如果js中想带数据,还是需要connect-src的白名单
#输出点在表单前,想构造csrf的时候,可以插入input标签,通过formaction和frommethod覆盖下方表单的submit或img,可以将表单内csrftoken通过referer带出。

在实际应用中CSP部署可能由于业务的需要和功能的设置,会有很多问题,正常站点功能的使用可能需要好好考虑一下。



以后再遇到CSP限制的漏洞或题目的时候,总算不至于没有思路了》。。。

参考链接

https://lorexxar.cn
https://chloe.re/2016/07/25/bypassing-paths-with-open-redirects-in-csp/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/
https://www.cnblogs.com/iamstudy/articles/bypass_csp_study.html
http://blog.portswigger.net/2016/12/bypassing-csp-using-polyglot-jpegs.html


发表评论 暂无评论

*