内容安全策略( CSP )

翻译正在进行中。

内容安全策略   (CSP) 是一个额外的安全层,有助于检测和减轻某些类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击。这些攻击用于从数据窃取到现场污染或恶意软件分发的一切。

CSP 被设计成向后兼容(除CSP2 在向后兼容有明确提及的不一致;  更多细节查看这里 章节1.1)。不支持CSP的浏览器也能与实现了CSP的服务器正常合作,反之亦然:不支持 CSP 的浏览器只会忽略它,如常运行,默认为网页内容使用标准的同源策略。如果网站不提供 CSP 头部,浏览器也使用标准的同源策略

为使CSP可用, 你需要确认你的网站返回  Content-Security-Policy  HTTP头部 ( 有时你会看到X-Content-Security-Policy头部, 那是旧版本,你无须再如此指定它).

或者,  <meta>  也能被用作策略的配置, 例如

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

威胁

跨站脚本攻击

CSP 的主要目标是减少和报告 XSS 攻击 ,XSS 攻击利用从服务器接受的可信内容。恶意脚本在受害者的浏览器中运行 因为浏览器信任其内容来源,甚至其并不来自它于真正应该来的地方.

通过设定域,即浏览器认可的可执行脚本的有效来源,CSP使得 减少甚至消除xss攻击所依赖的载体成为了可能。一个CSP兼容的浏览器应该仅执行从白名单域获取到的脚本文件, 忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性).

作为一种终极防护形式,始终不允许执行脚本的站点可以选择全面禁止脚本执行。

数据包嗅探攻击

除限制内容的加载域, 服务器还可指明哪种协议允许使用;比如 (安全角度的理想情况), 服务器可指定所有内容必须通过HTTPS加载. 一个完整的数据安全传输策略不仅强制使用HTPPS进行数据传输, 也为所有的cookie标记安全标识 cookies with the secure flag 以及提供自动的重定向使得HTTP页面导向HTTPS副本. 网站也可能使用  Strict-Transport-Security  HTTP头部确保连接它的浏览器只使用加密通道.

使用 CSP

配置内容安全策略涉及到添加 Content-Security-Policy  HTTP头部到一个页面并赋予值去控制用户代理为该页面加载的资源是被许可的。比如一个页面上传文件和显示图片,应该允许图片来自任何地方,但应表单操作限制到到一个明确端点,一个恰当的CSP设计帮助页面防止跨站脚本攻击。本文阐述如何恰当的构造这样的头部,并提供示例。

制定策略

你可以使用  Content-Security-Policy HTTP 来指定你的策略, 像这样:

Content-Security-Policy: policy

policy参数是一个描述你的CSP策略指令的字符串.

描述策略

一个策略由一系列策略指令所组成, 每个策略指令都通过明确的资源类型或者策略区域对策略进行描述。 你的策略应当包含一个   default-src 策略指令, 在其他资源类型没有符合自己的策略时应用该策略(有关完整列表查看default-src )。策略需要包含 default-src  或者 script-src 指令防止内联脚本运行, 并杜绝eval()的使用。 一个策略需要包含一个 default-src 或  style-src 指令去限制来自 一个 <style> )}} 元素或者style属性的內联样式。

示例:常见用例

这一部分提供常用的安全策略方案示例.

示例 1

一个网站管理者想要所有内容均来自站点自己 (这排除子域名.)

Content-Security-Policy: default-src 'self'

示例 2

一个网站管理者允许内容来自信任的域名极其子域名 (it doesn't have to be the same domain that the CSP is set on.)

Content-Security-Policy: default-src 'self' *.trusted.com

示例 3

一个网站管理者允许网页应用的用户在他们自己的内容中包含来自任何源的图片, 但是限制音频或视频需从信任的资源提供者(获得), 所有脚本必须从特定主机服务器获取可信的代码.

Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

在这里内容默认仅允许从文档的的所在的源获取, 但存在如下例外:

  • 图片可以从任何地方加载(注意 "*" 通配符).
  •  多媒体文件仅允许从 media1.com 和 media2.com 加载(不允许从这些站点的自域名).
  •  可运行脚本仅允许来自userscripts.example.com.

示例 4

一个网站管理者想要确保他的线上银行网站加载内容时仅使用SSL, 以避免攻击者窃听用户发出的请求.

Content-Security-Policy: default-src https://onlinebanking.jumbobank.com

该服务器仅允许获取来自域 onlinebanking.jumbobank.com、基于https载入的文档.

示例 5

 一个在线邮箱的管理者允许在邮件里包含HTML, 同样图片允许从任何地方加载, 但不允许JavaScript或者其他潜在的危险内容(从任意位置加载).

Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *

 注意这个示例并未指定script-src; 在此CSP示例中, 站点指定 default-src 指令, 意味着脚本文件仅允许从原始服务器获取.

对策略进行测试

为降低部署成本, .CSP可以用仅报告模式部署,CPS策略不是强制的。 一旦出现任何违反即报告给一个提供的URI地址, .此外,一个仅报告头部可以用来测试一个未来修订策略而不用实际部署它

你可以用Content-Security-Policy-Report-Only HTTP 头部来指定你的策略, 像这样:

Content-Security-Policy-Report-Only: policy

 如果Content-Security-Policy-Report-Only 头部和 Content-Security-Policy 同时存在一个响应中, 两个策略均有效,.在Content-Security-Policy 头部中指定的策略有强制性  而Content-Security-Policy-Report-Only中的策略仅产生报告而不具有强制性.

 浏览器支持CSP对于每个企图违反你所建立的策略都发送违规报告,如果策略里包含一个有效的report-uri 指令.

启用违例报告

默认情况下,并不发送违规报告 . 为启用违规报告, 你需要指定 report-uri 策略指令, 提供至少一个URI地址去递交报告:

Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi

然后设置你的服务器接收报告,他可以以你认为适当的方式保存或者处理这些报告

违例报告的语法

JSON对象报告包含以下数据:

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

违例报告样本

我们假设页面位于 http://example.com/signup.html. 它使用如下策略, 除stylesheets外不允许任何资源来自来自 cdn.example.com.

Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports

 signup.html 的HTML像这样:

<!DOCTYPE html>
<html>
  <head>
    <title>Sign Up</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    ... Content ...
  </body>
</html>

你能看出其中错误吗? Stylesheets  仅允许加载自cdn.example.com, 然而该页面企图从自己的源 (http://example.com)加载. 一个浏览器如能执行CSP将以POST请求的形式发送如下的违规报告到 http://example.com/_/csp-reports, 当文档被访问时:

{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
  }
}

如你所见,该报告在blocked-uri中包含有违规资源的完整路径 . 事情并非总是如此.比如, 当signup.html试图从   http://anothercdn.example.com/stylesheet.css加载CSS时, 浏览器将不会包含完整路径而仅有源(路径) (http://anothercdn.example.com). CSP技术规范对此古怪行为给出了解释 gives an explanation . 总体上, 这样是为了防止泄露跨源资源的敏感信息. 注意,  在example on violation reports 中该规范在这一部分有问题(blocked-uri should be "http://evil.example.com").

浏览器兼容性

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Content-Security-Policy251423.010157
base-uri40No35.0No2710
block-all-mixed-content(Yes)?48.0No(Yes)?
child-src40No45.0No2710
connect-src251423.0No157
default-src251423.0No157
disown-openerNoNoNoNoNoNo
font-src251423.0No157
form-action40No36.0No2710
frame-ancestors40No33.0No2610
frame-src251423.0No157
img-src251423.0No157
manifest-src(Yes)No41.0No(Yes)No
media-src251423.0No157
navigation-toNoNoNoNoNoNo
object-src251423.0No157
plugin-types40NoNoNo2710
referrer(Yes) — 56.0No37.0NoNoNo
report-toNoNoNoNoNoNo
report-uri251423.0No157
require-sri-forNoNo49.0NoNoNo
sandbox251450.010157
script-src251423.0No157
strict-dynamic52No52.0NoNoNo
style-src251423.0No157
upgrade-insecure-requests43No42.0No30No
worker-src56NoNoNoNoNo
FeatureAndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
Content-Security-Policy4.4(Yes)(Yes)23.0??7.1
base-uri?(Yes)No35.0No?9.3
block-all-mixed-content?(Yes)?48.0No??
child-src?(Yes)No45.0No?9.3
connect-src4.4(Yes)?23.0No?7.1
default-src4.4(Yes)?23.0No?7.1
disown-openerNoNoNoNoNoNoNo
font-src4.4(Yes)?23.0No?7.1
form-action?(Yes)No36.0No?9.3
frame-ancestors?(Yes)No33.0No?9.3
frame-src4.4(Yes)?23.0No?7.1
img-src4.4(Yes)?23.0No?7.1
manifest-src?(Yes)No41.0No?No
media-src4.4(Yes)?23.0No?7.1
navigation-toNoNoNoNoNoNoNo
object-src4.4(Yes)?23.0No?7.1
plugin-types?(Yes)NoNoNo?9.3
referrer(Yes) — 56.0(Yes) — 56.0No37.0NoNoNo
report-toNoNoNoNoNoNoNo
report-uri4.4(Yes)?23.0No?7.1
require-sri-forNoNoNo49.0NoNoNo
sandbox4.4(Yes)?50.010?7.1
script-src4.4(Yes)?23.0No?7.1
strict-dynamic?52NoNoNoNoNo
style-src4.4(Yes)?23.0No?7.1
upgrade-insecure-requests?43No42.0No?No
worker-src??NoNoNoNoNo

参见

文档标签和贡献者

 最后编辑者: WayneCui,