包阅导读总结
1. 关键词:CSP、跨站脚本攻击、内容安全策略、运营商劫持、指令集合
2. 总结:本文介绍了 XSS 终结者 – CSP 的理论与实践,包括策略类型、指令集合、使用方式、实践经验及项目实践数据,强调其能减少 XSS 和运营商劫持的内容注入攻击,分享了制定 CSP 方案的步骤。
3. 主要内容:
– CSP 理论与实践
– 介绍 CSP,包括两种策略类型(阻止执行和数据上报)
– 列举众多指令,如 default-src、script-src 等,并说明指令值示例
– CSP 的使用方式
– HTML Meta 标签,包括实际阻止策略和仅上报策略
– HTTP Header 方式,支持多个页面,兼容性更好
– 实践经验
– 制定 CSP 方案需谨慎,分三步:通过 HTML Meta 标签初步制定、使用 HTTP Header 的仅上报方式优化、改用实际拦截阻止策略
– 展示项目实践数据,日均劫持量大,攻击情况稳定持续,体现 CSP 强大
– 参考资料
思维导图:
文章地址:https://mp.weixin.qq.com/s/zjQHmVqA0xRbCcmCl84l8Q
文章来源:mp.weixin.qq.com
作者:joeyguo
发布时间:2024/8/4 0:02
语言:中文
总字数:2210字
预计阅读时间:9分钟
评分:85分
标签:前端开发,内容安全策略(CSP),前端安全,XSS防护,网络安全
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
前言
介绍了 CSP 的理论和实践,包括 CSP 的两种策略类型、指令集合、使用方式、实践经验以及项目实践数据,旨在减少跨站脚本攻击(XSS)和运营商劫持的内容注入攻击。今日前端早读课文章由 @joeyguo 分享。
正文从这开始~~
CSP 全称为 Content Security Policy,即内容安全策略。主要以白名单的形式配置可信任的内容来源,在网页中,能够使白名单中的内容正常执行(包含 JS,CSS,Image 等等),而非白名单的内容无法正常执行,从而减少跨站脚本攻击(XSS),当然,也能够减少运营商劫持的内容注入攻击。
示例:在 HTML 的 Head 中添加如下 Meta 标签,将在符合 CSP 标准的浏览器中使非同源的 script 不被加载执行。
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
不支持 CSP 的浏览器将自动会忽略 CSP 的信息,不会有什么影响。具体兼容性可在 caniuse 查看
CSP 语法组成
策略类型
CSP 有两种策略类型:
这两种策略类型的主要区别也可以从命名上看出,第一种对不安全的资源会进行阻止执行,而第二种只会进行数据上报,不会有实际的阻止。
当定义多个策略的时候,浏览器会优先采用最先定义的。
指令集合
CSP 的指令是组成内容来源白名单的关键,上面两种策略类型含有以下众多指令,可以通过搭配得到满足网站资源来源的白名单。
指令示例及说明
指令 | 取值示例 | 说明 |
---|---|---|
default-src | ‘self’ cdn.example.com | 定义针对所有类型(js/image/css/web font/ajax/iframe/ 多媒体等)资源的默认加载策略,某类型资源如果没有单独定义策略,就使用默认。 |
script-src | ‘self’ js.example.com | 定义针对 JavaScript 的加载策略 |
object-src | ‘self’ | 针对等标签的加载策略 |
style-src | ‘self’ css.example.com | 定义针对样式的加载策略 |
img-src | ‘self’ image.example.com | 定义针对图片的加载策略 |
media-src | ‘media.example.com’ | 针对object、embed、applet |
frame-src | ‘self’ | 针对 iframe 的加载策略 |
connect-src | ‘self’ | 针对 Ajax、WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为 400 的响应 |
font-src | font.qq.com | 针对 Web Font 的加载策略 |
sandbox | allow-forms allow-scripts | 对请求的资源启用 sandbox |
report-uri | /some-report-uri | 告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。不阻止任何内容,可以改用 Content-Security-Policy-Report-Only 头 |
base-uri | ‘self’ | 限制当前页面的 url(CSP2) |
child-src | ‘self’ | 限制子窗口的源 (iframe、弹窗等), 取代 frame-src(CSP2) |
form-action | ‘self’ | 限制表单能够提交到的源(CSP2) |
frame-ancestors | ‘none’ | 限制了当前页面可以被哪些页面以 iframe,frame,object 等方式加载(CSP2) |
plugin-types | application/pdf | 限制插件的类型(CSP2) |
指令值示例及说明
指令 | 示例 | 说明 |
---|---|---|
* | img-src * | 允许任何内容 |
‘none’ | img-src ‘none’ | 不允许任何内容 |
‘self’ | img-src ‘self’ | 允许同源内容 |
data: | img-src data: | 允许 data: 协议(如 base64 编码的图片) |
www.a.com | img-src www.a.com | 允许加载指定域名的资源 |
*.a.com | img-src *.a.com | 允许加载 a.com 任何子域的资源 |
https://img.com | img-srchttps://img.com | 允许加载 img.com 的 https 资源 |
https: | img-src https: | 允许加载 https 资源 |
‘unsafe-inline’ | script-src ‘unsafe-inline’ | 允许加载 inline 资源(style 属性,onclick,inline js 和 inline css 等等) |
‘unsafe-eval’ | script-src ‘unsafe-eval’ | 允许加载动态 js 代码,例如 eval () |
CSP 的使用方式
HTML Meta 标签
在这种形式中,Meta 标签主要含有两部分的 key-value:
http-equiv 的 value 为 CSP 的策略类型,而 content 则是声明指令集合,即白名单。如
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
在 HTML 的 head 中 添加上面的 Meta 标签,那么当浏览器支持 CSP 标准时,由于使用的是 Content-Security-Policy 实际阻止的策略,所以将会使得非同源的 script(根据指令集合来定)不会被加载及执行。
Meta 标签的 Content-Security-Policy-Report-Only 方式在当前(2016/5/19)多数移动端浏览器上表现正常,但是 不推荐 这样做,如 chrome 50 会产生如下的提示
The report-only Content Security Policy xxxxxxx was delivered via a element,which is disallowed. The policy has been ignored.
HTTP Header
通过 Meta 的方式很是简单,但当涉及到的页面较多时,使用 Meta 标签的方式需要在每个页面都各自加上。而如果通过服务端配置 HTML 返回的响应头 HTTP header 带上 CSP 的指令的话,那将能够一劳永逸,同时支持多个页面。下图为响应头
不仅如此,这种形式的 Content-Security-Policy-Report-Only 方式能够得到更好的兼容支持,也是推荐方式。
实践经验
CSP 的阻止加载及执行的方式相当强大,也因为它如此强大,所以在使用时更是要小心谨慎,毕竟,如一个不小心制定了错误的指令集合方案,那将可能导致阻止了正常文件的加载,影响业务功能,这是相当危险的。
一步步制定你的 CSP 方案
1、通过 HTML Meta 标签进行初步方案的制定 (meta 标签已不支持 report-uri 2019.7)
这种方式实现成本低,只对当前的 HTML 有效,从而能够进行逐步灰度。当然也存在上面提及的兼容性问题,但如果现在是在移动端上,或者在可预期的浏览器内核上跑的话,在兼容性满足的情况下,那还是可以通过这个方式进行 Report-Only。结合自己业务的资源情况以及在 Chrome 上调试制定初步方案。
2、使用 HTTP Header 的 Content-Security-Policy-Report-Only 方式进一步确定方案
由于上面的 Meta 标签存在一定的兼容问题,所以当我们制定了初步方案后,就可以开始使用 HTTP Header 的形式,小心驶得万年船,这里还是建议先使用 Report-Only 的方式,并指定上报的 url 来收集阻止的内容,通过上报的数据进行方案的优化,从而进一步确定具体方案。
3、HTTP Header 改用 Content-Security-Policy 策略进行实际拦截阻止
具体的 CSP 方案经过上面两轮洗礼,在分析完上报的数据,确定百无疏漏后,可将 HTTP Header 改用 Content-Security-Policy 策略,从而进行实际拦截阻止。
项目实践数据
笔者在实际项目中的进行了 CSP 上报拦截,通过上报的数据可以看到日均劫持达到 20000+ 的量,这对于页面本身 PV 并非很高的情况,在线 PV 占比竟达到了 4%;另一方面,从数据上也可以看出 拦截的主要来源(如下表)
3 月 1 日 – 4 月 4 日,CSP 拦截量
日期 | CSP 阻止量 | 在线 PV | 占比 |
---|---|---|---|
2016.03.31 | 23431 | 545872 | 4.31% |
2016.04.01 | 24459 | 619979 | 3.95% |
2016.04.02 | 20398 | 525055 | 3.88% |
2016.04.03 | 19938 | 475985 | 4.19% |
2016.04.04 | 23140 | 507329 | 4.56% |
4 月 4 日,CSP 拦截的 URL 前 5 名
排名 | 被 拦截的 URL | CSP 拦截量 |
---|---|---|
1 | http://wap.zjtoolbarc60.10086.cn:8080 | 5410 |
2 | http://wap.toolbar.sd.chinamobile.com:8080 | 2690 |
3 | http://119.188.105.1:8080 | 1498 |
4 | http://211.137.132.89:9090 | 947 |
5 | http://n.cosbot.cn | 675 |
从上面数据也可以看出,每天被攻击的情况呈现出一种稳定持续的倾向,而且这类攻击一般不是针对某个业务的,具备了普遍性,这样的影响范围可想而知。
不过,这也侧面烘托出 CSP 的强大,简单处理就能够阻止如此多的攻击,赶紧接入吧。
参考
https://www.w3.org/TR/CSP/#changes-from-level-1
http://w3c.github.io/webappsec-csp/
http://content-security-policy.com/
https://www.w3.org/TR/2012/CR-CSP-20121115/
关于本文
作者:@joeyguo
原文:https://github.com/joeyguo/blog/issues/5
这期前端早读课
对你有帮助,帮”赞“一下,
期待下一期,帮”在看” 一下 。