内容安全策略 (Content Security Policy) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击(尤其是XSS攻击)。

CSP通过指定浏览器认可的可执行脚本的有效来源使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个兼容CSP的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。

CSP 使用方法

有两种方法可以应用此策略:

  1. 配置服务器返回 Content-Security-Policy HTTP头部
    1
    2
    Content-Security-Policy: <policy-directive>; [<policy-directive>;]
    Content-Security-Policy-Report-Only: report-uri URI; [<policy-directive>;]
    Content-Security-Policy-Report-Only 表明对于每个企图违反内容安全策略的内容发送违规报告,发送地址为 report-uri 指定的地址。

违例报告包含以下内容:

key 内容
document-uri 发生违规的文档的URI
referrer 违规发生处的文档引用(地址)
blocked-uri 被CSP阻止的资源URI。如果被阻止的URI来自不同的源而非文档URI,那么被阻止的资源URI会被删减,仅保留协议,主机和端口号
violated-directive 违反的策略名称
original-policy 在 Content-Security-Policy HTTP 头部中指明的原始策略
  1. 在文档的 <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