CSP
CSP(Content Security Policy)是一个安全性标准,用于防止跨站脚本攻击。
设置方式主要是两种,一种是HTTP header,另一种是meta tag。
# header:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';
# meta tag:
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; object-src 'none';"
/>
默认不设置的话,是不做任何限制,所有来源的资源都可以被加载。
格式与取值
csp有多个指令组成用分号隔开,最后一组后面也加分号结尾。每个指令有指令名和允许的来源组成。
指令名 允许来源;
指令名常见取值:
default-src: 默认来源,是指其他没有专门设置的指令的默认值。script-src: js来源style-src: css来源img-src: 图片来源font-src: 字体来源connect-src: 连接来源(fetch xhr ws等api)media-src: 媒体来源object-src: 对象来源frame-src: iframe来源frame-ancestors: 允许当前页面被谁iframe嵌入worker-src: worker来源manifest-src: PWA manifest来源base-uri: 限制base标签form-action: 表单提交来源upgrade-insecure-requests: 自动升级到https协议report-uri: csp违规上报地址
常见source的取值:
- 当前域名:
'self'等价于https://www.example.com/* - 完全禁止:
'none'注意这里要加单引号因为是转有写法,下面的协议就不要加引号。 - 允许所有来源:
* - 允许某个协议:
https:,data:blob:注意冒号 - 通配符:
**.example.com*.example.com/path*.example.com:8080 - 内联:
unsafe-inline一般是针对内联js和css的控制,允许html中直接包含script/style标签。 - eval:
unsafe-eval允许eval执行动态js。 - nonce:
nonce-random随机生成一个nonce值,js标签中需要设定这个nonce值才被允许<script nonce="randomNonceValue">...,防止注入 - hash:
sha256-xxxx允许加载指定hash值的资源,防止注入 - wasm:
wasm-unsafe-eval这是js的策略取值,允许编译wasm文件
一个指令可以指定多个source,用空格隔开,例如
script-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';
插件
chrome插件的内置页面,可以通过配置文件中进行csp的配置,如果不配置默认等价于以下配置。
manifest.json
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self';",
"sandbox": "sandbox allow-scripts allow-forms allow-popups allow-modals; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self';"
}
并且chrome插件规定了最低配置项如下,这是最宽松的配置方式,不能比这个规则更宽松,例如添加unsafe-inline是不允许的,即不能在插件页面中内联js标签。
{
// ...
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
}
// ...
}
如果想要在插件的内置页面中再注入脚本或引用其他内容,可以使用sandbox,沙盒页面和普通页面都是普通的html,但是指定为沙盒页面之后,就不能再使用chrome.xxx的api了,这样做是为了防止插件脚本可以在沙盒页面中注入脚本,说白了。