CSP(Content Security Policy) 参考
在现代浏览器中通过声明新的 HTTP 返回头 Content-Security-Policy
帮助你减少 XSS 风险,并确定哪种动态资源允许被加载。
什么是 Content-Security-Policy
Content-Security-Policy 是在现代浏览器用于在文档或页面中增强安全性的一种 HTTP 返回头的名称。Content-Security-Policy 返回头允许你限制加载像 JavaScript、CSS 或者匹配的任何资源。
虽然主要使用 HTTP 返回头,但也可以使用 meta 标签。
术语 Content-Security-Policy 经常简写为 CSP。
Content-Security-Policy 有助于缓解哪些类型的攻击?
CSP 最初旨在减少跨站点脚本攻击(XSS)的攻击面,该规范的后续版本还可以防止其他形式的攻击,例如点击劫持(Click Jacking)。
点击劫持(Click Jacking),也被称为“用户界面矫正攻击”,是指攻击者使用多个透明或不透明的层来欺骗用户点击另一个页面上的按钮或链接,而他们本打算点击最高层的页面。
浏览器支持
所有主要的现代浏览器都支持内容安全策略(Content-Security-Policy),并且已经支持多年。Internet Explorer 不支持它。
返回头 | Chrome | FireFox | Safari | IE | Edge |
---|---|---|---|---|---|
Content-Security-Policy CSP Level 3 | 59+ 部分支持 | 58+ 部分支持 | - | - | 79+ 部分支持 |
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-22 | - | 10-11 | 12+ |
X-Webkit-CSP 过时 | 14-24 | - | 6 | - | - |
注意:需要知道的是 Content-Security-Policy
和 X-Content-Security-Policy
或 X-Webkit-CSP
在某些浏览器版本中不确定的行为,请避免使用不推荐的 X-*
返回头部。
CSP 指令参考
Content-Security-Policy
头部值包含一个或多个指令(声明如下),多个指令需要使用分号 ;
分隔。
该文档的编写基于 Content Security Policy Level 2 W3C Recommendation 和 CSP Level 3 W3C Working Draft。
default-src
default-src 是加载包括 JavaScript,img,CSS,Front,AJAX 请求,Frames,HTML5 媒体等内容的默认政策。查看来源列表了解更多可能的值。
default-src 'self' cdn.example.com;
CSP Level 1
script-src
声明允许的 JavaScript 来源。
script-src 'self' js.example.com;
CSP Level 1
style-src
声明允许的样式表来源。
style-src 'self' css.example.com;
CSP Level 1
img-src
声明允许的图片来源。
img-src 'self' img.example.com`
CSP Level 1
connect-src
申请 XMLHttpRequest
(AJAX), WebSocket
或 EventSource
的源。如果是不允许的请求浏览器将模仿 400
HTTP 状态码。
connect-src 'self';
CSP Level 1
font-src
声明允许的字体来源。
font-src font.example.com
CSP Level 1
object-src
声明允许的插件来源,相关元素 <object>
, <embed>
, 或 <applet>
。
object-src 'self'
CSP Level 1
media-src
声明允许的音频和视频来源,相关 <audio>
, <video>
HTML5 元素。
media-src media.example.com
CSP Level 1
frame-src
声明允许加载的 frame 来源。child-src
回退时使用这一指令。
定义了加载 frame 的有效来源。在 CSP Level 2 中,frame-src
被弃用,而改用 child-src
指令。CSP Leve 3 已不再使用 frame-src
,如果不存在,将继续使用 child-src
。
frame-src 'self'
CSP Level 1
sandbox
类似于 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
。
sandbox allow-forms allow-scripts
CSP Level 1
report-uri
指示浏览器以 POST 报告此 URI 的策略失败。你还可以在 HTTP 标头名称后面附加指令 -Report-Only
,以指示浏览器仅发送报告(不阻止任何内容)。
report-uri /some-report-uri
CSP Level 1
child-src
声明允许加载网络线程和像 <frame>
和 <iframe>
嵌套浏览上下文的来源。
child-src 'self'
CSP Level 2
form-action
声明允许使用在 HTML <form>
action 上的来源。
form-action 'self'
CSP Level 2
frame-ancestors
声明有效的 <frame>
<iframe>
<object>
<embed>
<applet>
等嵌入式资源的源。设置该指令为 'none'
差不多等价于 X-Frame-Options: DENY
。
frame-ancestors none
CSP Level 2
plugin-type
为插件 <object>
和 embed
引用的资源声明有效的文件 MIME 类型。为了加载 <applet>
必须声明 application/x-java-applet
。
plugin-type application/pdf
CSP Level 2
base-uri
定义了一组允许的 URL,可以在 HTML base
标签的 src
属性中使用。
base-uri 'self';
CSP Level 2
report-to
定义一个由 Report-To
HTTP 返回头定义的报告组名称。更多信息见报告 API。
report-to groupName;
CSP Level 3
worker-src
限制可以作为 Worker、SharedWorker 或 ServiceWorker 加载的 URL。
worker-src 'none';
CSP Level 3
manifest-src
限制可以作为应用 manifests 加载的 URL。
manifest-src 'none';
CSP Level 3
prefetch-src
声明请求预取和预渲染的有效来源,例如通过带有 rel="prefetch"
或 rel="prerender"
的 link
标签。
prefetch-src 'none'
CSP Level 3
navigate-to
限制了文件可以通过任何方式导航到的 URL。例如,当一个链接被点击,一个表单被提交,或者 window.location
被调用。如果 form-action
是存在的,那么这个指令在表单提交时被忽略。chrome 实现状态
navigate-to example.com
CSP Level 3
来源列表参考
所有以 -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>
文章由 吳文俊 翻译,原文地址 Content Security Policy Reference,转载请注明出处。