内容安全策略 (Content Security Policy) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击(尤其是XSS攻击)。
CSP通过指定浏览器认可的可执行脚本的有效来源使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个兼容CSP的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。
CSP 使用方法
有两种方法可以应用此策略:
- 配置服务器返回
Content-Security-Policy
HTTP头部Content-Security-Policy-Report-Only 表明对于每个企图违反内容安全策略的内容发送违规报告,发送地址为 report-uri 指定的地址。1
2Content-Security-Policy: <policy-directive>; [<policy-directive>;]
Content-Security-Policy-Report-Only: report-uri URI; [<policy-directive>;]
违例报告包含以下内容:
key | 内容 |
---|---|
document-uri | 发生违规的文档的URI |
referrer | 违规发生处的文档引用(地址) |
blocked-uri | 被CSP阻止的资源URI。如果被阻止的URI来自不同的源而非文档URI,那么被阻止的资源URI会被删减,仅保留协议,主机和端口号 |
violated-directive | 违反的策略名称 |
original-policy | 在 Content-Security-Policy HTTP 头部中指明的原始策略 |
- 在文档的
<meta>
元素里配置该策略1
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
如果 HTTP 头与 Meta 定义同时存在,则优先采用 HTTP 中的定义。
CSP 指令
内容安全策略可以配置多个,一个策略由一系列策略指令所组成,每个策略指令都描述了一个针对某个特定类型资源以及生效范围的策略。
策略指令分为五种:获取指令(Fetch directives)、文档指令(Document directives)、导航指令(Navigation directives)、报告指令(Reporting directives)、其它指令(Other directives)
CSP 指令可取的key
获取指令 | 作用 |
---|---|
child-src | 为 web workers 和其他内嵌浏览器内容(例如用 <frame> 和 <iframe> 加载到页面的内容)定义合法的源地址,相当于 frame-src 和 worker-src |
connect-src | 限制能通过脚本接口加载的URL |
default-src | 为其他取指令提供备用服务 |
font-src | 设置允许通过@font-face加载的字体源地址 |
frame-src | 设置允许通过类似 <frame> 和 <iframe> 标签加载的内嵌内容的源地址 |
img-src | 限制图片和图标的源地址 |
manifest-src | 限制应用声明文件的源地址 |
media-src | 限制通过 <audio> 、 <video> 或 <track> 标签加载的媒体文件的源地址 |
object-src | 限制 <object> 、<embed> 、<applet> 标签的源地址 |
prefetch-src | 指定预加载或预渲染的允许源地址 |
script-src | 限制JavaScript的源地址 |
style-src | 限制层叠样式表文件源 |
webrtc-src | 指定WebRTC连接的合法源地址 |
worker-src | 限制 Worker、SharedWorker 或者 ServiceWorker 脚本源 |
文档指令 | 作用 |
---|---|
base-uri | 限制在DOM中 <base> 元素可以使用的URL |
plugin-types | 通过限制可以加载的资源类型来限制哪些插件可以被嵌入到文档中 |
sandbox | 类似 <iframe> sandbox 属性,为请求的资源启用沙盒 |
导航指令 | 作用 |
---|---|
form-action | 限制能被用来作为给定上下文的表单提交的目标 URL |
frame-ancestors | 指定可能嵌入页面的有效父项 <frame> , <iframe> , <object> , <embed> , <applet> |
navigation-to | 限制文档可以通过以下任何方式访问URL (a, form, window.location, window.open, etc.) |
报告指令 | 作用 |
---|---|
report-uri | 当出现可能违反CSP的操作时,让客户端提交报告。这些违规报告会以JSON文件的格式通过POST请求发送到指定的URI |
report-to | 触发 SecurityPolicyViolationEvent |
其它指令 | 作用 |
---|---|
block-all-mixed-content | 当使用HTTPS加载页面时阻止使用HTTP加载任何资源 |
require-sri-for | 需要使用 SRI 作用于页面上的脚本或样式 |
upgrade-insecure-requests | 让浏览器把一个网站所有的不安全 URL(通过 HTTP 访问)当做已经被安全的 URL 链接(通过 HTTPS 访问)替代 |
CSP 指令可取的value
指令值 | 指令值示例 | 说明 |
---|---|---|
* | img-src * | 允许任何内容 |
‘none’ | img-src ‘none’ | 不允许任何内容 |
‘self’ | img-src ‘self’ | 允许来自相同源内容(相同协议、域名和端口) |
data: | img-src data: | 允许 data: 协议 |
www.example.com | img-src img.example.com | 允许加载指定域名的资源 |
*.example.com | img-src *.example.com | 允许加载 example.com 任何子域的资源 |
‘unsafe-inline’ | script-src ‘unsafe-inline’ | 允许加载 inline 资源 |
‘unsafe-eval’ | script-src ‘unsafe-eval’ | 允许加载动态 js 代码(eval) |
常见策略
允许加载同源的图片、脚本、AJAX和CSS资源,并阻止加载其他任何资源
1 | default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; |
参考资料
MDN docs Content-Security-Policy
MDN docs CSP
w3 CSP1
w3 CSP2
w3 github Upgrade Insecure Requests
w3 github Subresource Integrity
w3 github Mixed Content
w3 github CSP3