欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 10:47:12
...

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

使用方式:

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

调试工具: Chrome插件——modheader。通过随意设置响应头来测试CSP
简单过一遍常见的指令
获取资源相关的指令

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

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

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配置

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

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

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

schema配置

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

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

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

self

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

unsafe-inline

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

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

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

当设置这个header的页面加载www.qq.com之外的图片的时候,将会阻塞加载,并在控制台报错,再上报到 https://a.b.c/report
前端的CSP & CSP如何落地,了解一下
前端的CSP & CSP如何落地,了解一下
前端的CSP & CSP如何落地,了解一下
上报的数据就是这些,浏览器帮你拼装好了。当然,随便写的路径肯定是404的,这个自己起一个服务器就可以收到这个上报

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

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

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

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

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

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

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

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

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方式

最后

如果你现在也想学习前端开发技术,在学习前端的过程当中有遇见任何关于学习方法,学习路线,学习效率等方面的问题,你都可以加入到我的Q群中:前114中6649后671,里面有许多前端学习资料以及2020大厂面试真题 点赞、评论、转发 即可免费获取,希望能够对你们有所帮助。
前端的CSP & CSP如何落地,了解一下