简介
内容安全策略 (CSP) 是一个额外的安全层,用于允许站点的管理者控制页面上哪些资源能够被用户代理程序加载。以阻止包括跨站脚本 (XSS) 、数据注入等攻击。
使用
在HTTP头部指定策略
1 | Content-Security-Policy: policy |
使用meta标签指定策略
1 | <meta http-equiv="content-security-policy" content="policy"> |
示例
存在漏洞的服务器
写一个反射式的XSS服务吧:
1 | <?php echo $_GET['xss'];?> |
bengin.js:
1 | alert("I'm benign~~~"); |
evil.js:
1 | alert("I'm evil!"); |
毫无疑问它是存在漏洞的,不过无奈现在chrome的反射型xss防御做的太好了,我们只能先暂时关闭它(j加header)来降低实验难度,在BP里面加一个”X-XSS-Protection:0”的Header:
我在8000端口又起了一个http服务,接着随心所欲的XSS:
应用默认策略
配置该站点的内容均来自同源:
1 | Content-Security-Policy: default-src 'self' |
其中,default-src
是指若其他元素来源的规则(如script-src
,img-src
)没有设置的情况下,默认使用default-src
的配置,self
是同源。
设置后可以看到xss被拦截,以为恶意脚本来自不同的源:
信任多个域名
元素的可信来源可以有多个,比如:
1 | Content-Security-Policy: default-src 'self' *.trusted.com |
来源配置
*
: 允许所有none
:禁止加载任何路径的资源self
:允许加载同源的资源data:
:允许通过数据模式加载资源domain.ccc.com
:允许加载匹配域名的资源*.ccc.com
:允许加载匹配域名的资源https://img.ccc.com
:允许加载https方式的域名资源unsafe-inline
:允许使用内联元素unsafe-eval
:允许执行eval函数
精确控制
其他可以设置的源有:
child-src
connect-src
font-src
frame-src
img-src
manifest-src
media-src
object-src
script-src
style-src
worker-src
sandbox allow-forms allow-scripts
:授权一个沙箱来请求iframe sanbox等类似属性的资源,沙箱默认使用同源策略,可增加配置,如allow-scripts
,允许跨站script
例如,信任任意的图片来源,但是只信任本站的其他来源:
1 | Content-Security-Policy: default-src 'self'; img-src * |
内嵌脚本
新版的默认策略已经封禁了内嵌脚本的执行,这意味着即使我们不引入外部js,而直接在<script>
标签里面写东西也是不允许的(这也造成巧妙地绕过CSP:欺骗CSP执行任意代码一文的失效:
那么正常的需求怎么办呢?正常服务器发送网页的时候,需要在策略中告诉浏览器一个随机生成的token。
1 | Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa' |
页面内嵌脚本必须有这个token才能执行:1
<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa> // some code </script>
测试策略
可以将CSP配置为仅报告模式,这样即使出现违规,CSP也只是报告这个行为而不强制拦截:
1 | Content-Security-Policy-Report-Only: default-src 'self'; report-uri http://127.0.0.1:8000 |
其他关键字
兼容性
毫无疑问很多浏览器是不支持这个字段的,详细的支持参见https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP
参考链接
- 内容安全策略( CSP ),https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP
- 巧妙地绕过CSP:欺骗CSP执行任意代码,https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa