CSP(Content Security Policy) 参考

在现代浏览器中通过声明新的 HTTP 返回头 Content-Security-Policy 帮助你减少 XSS 风险,并确定哪种动态资源允许被加载。

#浏览器支持

返回头 Chrome FireFox Safari IE Edge
Content-Security-Policy CSP Level 2 40+ 31+ 10+ - 15+
Content-Security-Policy CSP 1.0 25+ 23+ 7+ - 12+
X-Content-Security-Policy 不推荐 - 4+ - 10+ 12+
X-Webkit-CSP 不推荐 14+ - 6+ - -

信息来源:caniuse.com/contentsecuritypolicycaniuse.com/contentsecuritypolicy2Mozilla

注意:需要知道的是 Content-Security-PolicyX-Content-Security-PolicyX-Webkit-CSP 在某些浏览器版本中不确定的行为,请避免使用不推荐的 X-* 返回头部。

#CSP 指令参考

Content-Security-Policy 头部值包含一个或多个指令(声明如下),多个指令需要使用分号 ; 分隔。该文档的编写基于 W3C: Content Security Policy 1.0

指令 示例值 说明
default-src 'self' cdn.example.com default-src 是加载包括 JavaScript,img,CSS,Front,AJAX 请求,Frames,HTML5 媒体等内容的默认政策。查看来源列表了解更多可能的值。
CSP Level 1
25+ 23+ 7+ 12+
script-src 'self' js.example.com 声明允许的 JavaScript 来源。
CSP Level 1
25+ 23+ 7+ 12+
style-src 'self' css.example.com 声明允许的样式表来源。
CSP Level 1
25+ 23+ 7+ 12+
img-src 'self' img.example.com 声明允许的图片来源。
CSP Level 1
25+ 23+ 7+ 12+
connect-src 'self' 申请 XMLHttpRequest(AJAX), WebSocketEventSource 的源。如果是不允许的请求浏览器将模仿 400 HTTP 状态码。
CSP Level 1
25+ 23+ 7+ 12+
font-src font.example.com 声明允许的字体来源。
CSP Level 1
25+ 23+ 7+ 12+
object-src 'self' 声明允许的插件来源,相关元素 <object>, <embed>, 或 <applet>
CSP Level 1
25+ 23+ 7+ 12+
media-src media.example.com 声明允许的音频和视频来源,相关 <audio>, <video> HTML5 元素。
CSP Level 1
25+ 23+ 7+ 12+
frame-src 'self' 声明允许加载的 frame 来源。child-src 回退时使用这一指令。
不推荐
sandbox allow-forms allow-scripts 类似于 iframe sandbox 属性请求的资源设置允许沙盒,沙盒应用相同源,禁止弹窗,插件和阻止脚本执行。你可以保持空白值在限制的地方,或者添加值:allow-forms allow-same-origin allow-scripts allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to-escape-sandbox, 和 allow-top-navigation
CSP Level 1
25+ 50+ 7+ 12+
report-uri /some-report-uri 指示浏览器以 POST 报告此 URI 的策略失败。你还可以在 HTTP 标头名称后面附加指令 -Report-Only,以指示浏览器仅发送报告(不阻止任何内容)。
CSP Level 1
25+ 23+ 7+ 12+
child-src 'self' 声明允许加载网络线程和像 <frame><iframe> 嵌套浏览上下文的来源。
CSP Level 2
40+ 45+ 15+
form-action 'self' 声明允许使用在 HTML <form> action 上的来源。
CSP Level 2
40+ 36+ 15+
frame-ancestors none 声明有效的 <frame> <iframe> <object> <embed> <applet> 等嵌入式资源的源。设置该指令为 'none' 差不多等价于 X-Frame-Options: DENY
CSP Level 2
39+ 33+ 15+
plugin-type application/pdf 为插件 <object>embed 引用的资源声明有效的文件 MIME 类型。为了加载 <applet> 必须声明 application/x-java-applet
CSP Level 2
40+ 15+

#来源列表参考

所有以 -src 结尾的指令提供相似的值来源。多个来源值可以使用空格分隔,但 none 是例外的,它只允许单独唯一值。

来源 例子 说明
* img-src * 通配符,允许除了 data: blob: filesystem: 协议以外的任何 URL 来源。
'none' object-src 'none' 阻止从任何来源加载资源。
'self' script 'self' 允许从相同的源加载资源(相同的协议,主机名和端口号)。
data: img-src 'self' data: 允许通过 data 协议加载资源(例如 Base64 编码图片)。
domain.example.com img-src domain.example.com 允许从指定域名加载资源。
*.example.com img-src *.example.com 允许从 example.com 任何子域名加载资源。
https://cdn.com img-src https://cdn.com 仅允许从指定域名并以 HTTPS 方式加载资源。
https: img-src https: 允许从任何域名以 HTTPS 方式加载资源。
'unsafe-inline' script-src 'unsafe-inline' 允许使用行内元素如 style 属性, onclick, 或 script 标签体 和 javascript: URLs
'unsafe-eval' script-src 'unsafe-eval' 允许执行不安全的动态代码,如 JavaScript eval()
'sha256-' script-src 'sha256-xyz...' 如果行内 script 或 CSS 的哈希值匹配给定的哈希头部,则允许执行。当前支持 SHA256, SHA384 或 SHA512。CSP Level 2
'nonce-' script-src 'nonce-r@nd0m' 如果行内 script 或 CSS(如 <script nonce="r@nd0m">)标签包含 nonce 属性且匹配指定的 CSP 头部 nonce 值,则允许执行。nonce 应该是一个安全的随机字符串,并且不应该重复使用。CSP Level 2
'strict-dynamic' script-src 'strict-dynamic' 允许被允许的脚本通过非“插入分析器”的脚本元素加载其它脚本(例如 document.createElement('script'); 被允许)。CSP Level 3
'unsafe-hashes' script-src 'unsafe-hashes' 'sha256-abc...' 允许你在事件处理程序中启用脚本(例如 onclick)。不适用于 javascript: 或内联<script>CSP Level 3

#CSP(Content-Security-Policy) 例子

这里有一些内容安全策略(CSP)的常用用法:

#允许来自相同源的任何资源

default-src 'self';

#仅允许来自相同源的脚本

script-src 'self';

#允许 Google Analytics,Google AJAX CDN 和相同源

script-src 'self' www.google-analytics.com ajax.googleapis.com;

#基本策略

该策略允许从相同源加载图片,脚本,AJAX 和 CSS,并且不允许其它来源的任何资源(如 object,frame,媒体,等等)。这是针对许多网站很好的策略。

default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';

#CSP(Content-Security-Policy) 错误信息

在 Chrome 中,当脚本违反内容安全策略(Content-Security-Policy),你将在 Chrome 开发者工具中得到下面的信息:

Refused to load the script 'script-uri' because it violates the following Content Security Policy directive: "your CSP directive".

在 Firefox 中你可能在 Web 开发者工具中看到如下信息:

Content Security Policy: A violation occurred for a report-only CSP policy ("An attempt to execute inline scripts has been blocked"). The behavior was allowed, and a CSP report was sent.

除了控制台信息,亦会触发 securitypolicyviolation 事件。了解更多 w3.org

#服务端配置

任何服务端编程环境都应该允许你发送自定义 HTTP 返回头。你也可以使用你的网络服务器发送返回头。

#Apache Content-Security-Policy 返回头

添加下面的代码到 httpd.conf 在你的 VirtualHost 或者一个 .htaccess 文件:

Header set Content-Security-Policy "default-src 'self';"

#Nginx Content-Security-Policy 返回头

在你的 server {} 块中添加:

add_header Content-Security-Policy "default-src 'self';";

也可以添加 always 到尾部以保证 nginx 忽略返回码发送返回头。

#IIS Content-Security-Policy 返回头

可以在 IIS GUI 中管理使用的 HTTP 返回头,或者添加下面的代码到你的 web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Content-Security-Policy" value="default-src 'self';" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

#CSP 资源

想要了解更多关于 CSP 的信息,阅读下面的链接: