前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >嘿,前端的CSP & CSP如何落地,了解一下?

嘿,前端的CSP & CSP如何落地,了解一下?

作者头像
lhyt
发布2022-03-08 11:11:22
2.9K1
发布2022-03-08 11:11:22
举报
文章被收录于专栏:lhyt前端之路

CSP(Content-Security-Policy)是一个HTTP response header, 它描述允许页面控制用户代理能够为指定的页面加载哪些资源, 可防止XSS攻击

使用方式:

代码语言:javascript
复制
Content-Security-Policy: 指令1 指令1的值1 指令1的值2 指令1的值3; 指令2 指令2的值1 指令2的值2

调试工具: Chrome插件——modheader。通过随意设置响应头来测试CSP

MDN文档

简单过一遍常见的指令

获取资源相关的指令

代码语言:javascript
复制
font-src
frame-src
img-src
script-src
media-src
style-src
...等等,其他参考MDN

这些src规定了页面只能加载里面所设置的font、iframe、img、script...这些资源,比如有一个html页面的response header是:

代码语言:javascript
复制
Content-Security-Policy: img-src a.b.c; script-src 'unsafe-inline' a.b.c; style-src 'self'

表示只能加载来自a.b.c域的图片、a.b.c域的脚本和行内脚本(如<script>console.log(1)</script>)、只能加载自己域下的style

这些xx-src,一般常见的配置有:

host配置

可精确匹配也可通配符匹配:

代码语言:javascript
复制
https://*.qq.com
https://a.b.com
*.qq.com
www.qq.com

最后,有一个通用化配置——default-src,你给了它什么值,其他几个指令就默认什么值。其他指令如果有设置,那自身的值会覆盖default-src的值

schema配置

代码语言:javascript
复制
data: => dataURI,比如base64
blob: => blob资源
http: => 顾名思义
https: => 顾名思义
...一般是这些比较多,其他参考MDN

注意,要写冒号。为了防止误解,所以上面用 =>描述了。eg:

代码语言:javascript
复制
Content-Security-Policy: img-src http: data:; style-src 'self'

self

只能加载自身相同的域资源,其他如data:blob:就不能了

unsafe-inline

行内,一般针对于style和script标签。没有这个,就不能使用行内标签了

上报指令

如果设置了上报指令的上报地址,当页面有加载不合法的资源,将会往那里上报。比如

代码语言:javascript
复制
Content-Security-Policy: img-src www.qq.com; report-uri https://a.b.c/report

当设置这个header的页面加载www.qq.com之外的图片的时候,将会阻塞加载,并在控制台报错,再上报到https://a.b.c/report

上报的数据就是这些,浏览器帮你拼装好了。当然,随便写的路径肯定是404的,这个自己起一个服务器就可以收到这个上报

目前阶段,一般使用report-uri上报,用法是后面接上上报地址。report-to是另一个上报指令,功能更丰富,使用方式稍微麻烦一点

代码语言:javascript
复制
Content-Security-Policy: report-uri https://a.b.c/report
Content-Security-Policy: report-uri /current_page_report

其他的指令比较简单,但使用场景可能不是很多,有兴趣去MDN看看

CSP如何在自己前端项目落地

第一阶段

使用Content-Security-Policy-Report-Only头而不是直接使用Content-Security-PolicyContent-Security-Policy-Report-Only顾名思义,只是上报,不会阻塞资源加载。因此页面改造第一步是先通过仅仅上报的头来观察一段时间,看看哪些资源哪些case是不符合CSP的,漏掉的加上,不合理的干掉

初始化资源指令,给default-src一个'self',让资源都默认走本地。其次通过其他方式改变header(我使用了浏览器插件的方式,比较简单暴力。其实还可以自己开个服务器做代理、本地起nginx加头等等方式都可以),观察控制台报错,再把漏掉的资源补齐,如cdn站点、base64的data:、第三方sdk、图片cos存储地址等都是最常见的case

补齐资源,让页面不再报错;一些是不太优雅或者有风险的case,自己再另外衡量要不要换另一种方式引入或者去掉

另外,如果有iframe、worker、websocket这些的,也需要配置一下CSP

第二阶段

观察一段时间后,自己的上报站点如果有CSP报错,那么去解决掉,然后继续观察一段时间重复同样的步骤,直到没有CSP错误。当上报站点再也没有CSP错误或者错误比较少能接受范围内,将Content-Security-Policy-Report-Only换成Content-Security-Policy再次上线

线上不可能也要人家装插件啊、代理啊,如何修改这个头

一般页面就在nginx上对html配response header

代码语言:javascript
复制
location  ~* .(html)$ {
    add_header Content-Security-Policy "img-src http: data:; style-src 'self'";
}

如果是ssr项目或者前后端不分离项目,服务端直接setheader即可

如果是新需求可能涉及到新的资源引入怎么办

确定知道的源,新增header配置;不确定的最好自己设置一个中转服务,或者重新思考一下需求/技术方案合理性;实在没办法,需要删除default-src设置,并且img-src需要妥协一下了

如果有新页面上线且旧页面已经不使用report-only了怎么办

nginx配置一下,不同的页面使用不同的头

代码语言:javascript
复制
location  /a {
    add_header Content-Security-Policy "img-src http: data:; style-src 'self'";
}

location  /b {
    add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri https://a.b.c/report";
}

服务端的话,判断一下页面路径,采用不同的setheader方式

最后

页面又安全一分了,心里踏实,起码可以防止很多很多低端攻击手法了。再回头翻翻网上那些经典的攻击手法和案例,是不是可以防掉很多了。不过还是有办法破解的。。。前面说了用什么来调试来着?有想法的,评论区留下自己的想法或者方案,一起交流一下吧

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/09/03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简单过一遍常见的指令
    • 获取资源相关的指令
      • 上报指令
      • CSP如何在自己前端项目落地
        • 第一阶段
          • 第二阶段
          • 最后
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档