0%

内容安全策略CSP学习笔记

简介

内容安全策略 (CSP) 是一个额外的安全层,用于允许站点的管理者控制页面上哪些资源能够被用户代理程序加载。以阻止包括跨站脚本 (XSS) 、数据注入等攻击。

使用

在HTTP头部指定策略

1
Content-Security-Policy: policy

使用meta标签指定策略

1
<meta http-equiv="content-security-policy" content="policy">

示例

存在漏洞的服务器

写一个反射式的XSS服务吧:

1
2
<?php echo $_GET['xss'];?>
<script src="/js/benign.js"></script>

bengin.js:

1
alert("I'm benign~~~");

evil.js:

1
alert("I'm evil!");

毫无疑问它是存在漏洞的,不过无奈现在chrome的反射型xss防御做的太好了,我们只能先暂时关闭它(j加header)来降低实验难度,在BP里面加一个”X-XSS-Protection:0”的Header:

1548835133910

我在8000端口又起了一个http服务,接着随心所欲的XSS:

1548835338494

应用默认策略

配置该站点的内容均来自同源:

1
Content-Security-Policy: default-src 'self'

其中,default-src是指若其他元素来源的规则(如script-srcimg-src)没有设置的情况下,默认使用default-src的配置,self是同源。

设置后可以看到xss被拦截,以为恶意脚本来自不同的源:

1548835861387

信任多个域名

元素的可信来源可以有多个,比如:

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函数

精确控制

其他可以设置的源有:

例如,信任任意的图片来源,但是只信任本站的其他来源:

1
Content-Security-Policy: default-src 'self'; img-src *

内嵌脚本

新版的默认策略已经封禁了内嵌脚本的执行,这意味着即使我们不引入外部js,而直接在<script>标签里面写东西也是不允许的(这也造成巧妙地绕过CSP:欺骗CSP执行任意代码一文的失效:

1548837928332

那么正常的需求怎么办呢?正常服务器发送网页的时候,需要在策略中告诉浏览器一个随机生成的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

http://127.0.0.1:8000收到的报告如下:

1548838217202

其他关键字

兼容性

毫无疑问很多浏览器是不支持这个字段的,详细的支持参见https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP

参考链接