Javascript 内容安全策略如何运作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/30280370/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does Content Security Policy work?
提问by Schlaus
I'm getting a bunch of errors in the developer console:
我在开发者控制台中收到一堆错误:
Refused to evaluate a string
Refused to execute inline script because it violates the following Content Security Policy directive
Refused to load the script
Refused to load the stylesheet
拒绝评估字符串
拒绝执行内联脚本,因为它违反了以下内容安全策略指令
拒绝加载脚本
拒绝加载样式表
What's this all about? How does Content Security Policy work? How do I use the Content-Security-PolicyHTTP header?
这是怎么回事?内容安全策略如何运作?如何使用Content-Security-PolicyHTTP 标头?
Specifically, how to...
具体来说,如何...
- ...allow multiple sources?
- ...use different directives?
- ...use multiple directives?
- ...handle ports?
- ...handle different protocols?
- ...allow file://protocol?
- ...use inline styles, scripts, and tags <style>and<script>?
- ...allow eval()?
- ...允许多个来源?
- ...使用不同的指令?
- ...使用多个指令?
- ...处理端口?
- ...处理不同的协议?
- ...允许file://协议?
- ...使用内联样式、脚本和标签<style>以及<script>?
- ……允许eval()吗?
And finally:
最后:
- What exactly does 'self'mean?
- 究竟是什么'self'意思?
回答by Schlaus
The Content-Security-Policymeta-tag allows you to reduce the risk of XSSattacks by allowing you to define where resources can be loaded from, preventing browsers from loading data from any other locations. This makes it harder for an attacker to inject malicious code into your site.
该Content-Security-Policy元标记可以让你减少风险XSS允许你定义在资源可以被加载,从而防止数据加载浏览器从任何其它位置的攻击。这使得攻击者更难将恶意代码注入您的站点。
I banged my head against a brick wall trying to figure out why I was getting CSP errors one after another, and there didn't seem to be any concise, clear instructions on just how does it work. So here's my attempt at explaining somepoints of CSP briefly, mostly concentrating on the things I found hard to solve.
我用头撞了一堵砖墙,试图弄清楚为什么我一个接一个地收到 CSP 错误,但似乎没有任何关于它是如何工作的简洁明了的说明。所以这里是我尝试简要解释CSP 的一些要点,主要集中在我发现难以解决的问题上。
For brevity I won't write the full tag in each sample. Instead I'll only show the contentproperty, so a sample that says content="default-src 'self'"means this:
为简洁起见,我不会在每个示例中写下完整的标签。相反,我将只显示该content属性,因此示例说明content="default-src 'self'"如下:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
1. How to allow multiple sources?
1.如何允许多个来源?
You can simply list your sources after a directive as a space separated list:
您可以简单地在指令后将您的源作为空格分隔的列表列出:
content="default-src 'self' https://example.com/js/"
Note that there are no quotes around parameters other than the specialones, like 'self'. Also, there's no colon (:) after the directive. Just the directive, then a space-separated list of parameters.
请注意,除了特殊参数(如'self'. 此外,:指令后没有冒号 ( )。只是指令,然后是空格分隔的参数列表。
Everything below the specified parameters is implicitly allowed. That means that in the example above these would be valid sources:
隐式允许低于指定参数的所有内容。这意味着在上面的示例中,这些将是有效的来源:
https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js
These, however, would not be valid:
但是,这些是无效的:
http://example.com/js/file.js
^^^^ wrong protocol
https://example.com/file.js
                   ^^ above the specified path
2. How to use different directives, what do they each do?
2. 如何使用不同的指令,它们分别是做什么的?
The most common directives are:
最常见的指令是:
- default-srcthe default policy for loading javascript, images, CSS, fonts, AJAX requests, etc
- script-srcdefines valid sources for javascript files
- style-srcdefines valid sources for css files
- img-srcdefines valid sources for images
- connect-srcdefines valid targets for to XMLHttpRequest (AJAX), WebSockets or EventSource. If a connection attempt is made to a host that's not allowed here, the browser will emulate a- 400error
- default-src加载 javascript、图像、CSS、字体、AJAX 请求等的默认策略
- script-src定义 javascript 文件的有效来源
- style-src定义 css 文件的有效来源
- img-src定义图像的有效来源
- connect-src为 XMLHttpRequest (AJAX)、WebSockets 或 EventSource 定义有效目标。如果对此处不允许的主机进行连接尝试,浏览器将模拟- 400错误
There are others, but these are the ones you're most likely to need.
还有其他的,但这些是您最有可能需要的。
3. How to use multiple directives?
3. 如何使用多个指令?
You define all your directives inside one meta-tag by terminating them with a semicolon (;):
您可以在一个元标记中定义所有指令,方法是用分号 ( ;)终止它们:
content="default-src 'self' https://example.com/js/; style-src 'self'"
4. How to handle ports?
4.如何处理端口?
Everything but the default ports needs to be allowed explicitly by adding the port number or an asterisk after the allowed domain:
除了默认端口之外的所有内容都需要通过在允许的域后添加端口号或星号来明确允许:
content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"
The above would result in:
以上将导致:
https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port
https://ajax.googleapis.com - OK
http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed
http://example.com:123/free/stuff/file.js - OK
As I mentioned, you can also use an asterisk to explicitly allow all ports:
正如我提到的,您还可以使用星号来明确允许所有端口:
content="default-src example.com:*"
5. How to handle different protocols?
5、如何处理不同的协议?
By default, only standard protocols are allowed. For example to allow WebSockets ws://you will have to allow it explicitly:
默认情况下,只允许标准协议。例如,要允许 WebSockets,ws://您必须明确允许它:
content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports
6. How to allow the file protocol file://?
6.如何允许文件协议file://?
If you'll try to define it as such it won't work. Instead, you'll allow it with the filesystemparameter:
如果您尝试这样定义它,它将不起作用。相反,您将使用filesystem参数允许它:
content="default-src filesystem"
7. How to use inline scripts and style definitions?
7. 如何使用内联脚本和样式定义?
Unless explicitly allowed, you can't use inline style definitions, code inside <script>tags or in tag properties like onclick. You allow them like so:
除非明确允许,否则您不能使用内联样式定义、<script>标签内的代码或标签属性(如onclick. 你允许他们像这样:
content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"
You'll also have to explicitly allow inline, base64 encoded images:
您还必须明确允许内联、base64 编码的图像:
content="img-src data:"
8. How to allow eval()?
8.如何允许eval()?
I'm sure many people would say that you don't, since 'eval is evil' and the most likely cause for the impending end of the world. Those people would be wrong. Sure, you can definitely punch major holes into your site's security with eval, but it has perfectly valid use cases. You just have to be smart about using it. You allow it like so:
我敢肯定很多人会说你不会,因为“eval 是邪恶的”,而且是世界末日即将来临的最有可能的原因。那些人会错的。当然,您绝对可以使用 eval 在您站点的安全性中打出重大漏洞,但它具有完全有效的用例。你只需要聪明地使用它。你允许它像这样:
content="script-src 'unsafe-eval'"
9. What exactly does 'self'mean?
9. 究竟是什么'self'意思?
You might take 'self'to mean localhost, local filesystem, or anything on the same host. It doesn't mean any of those. It means sources that have the same scheme (protocol), same host, and same port as the file the content policy is defined in. Serving your site over HTTP? No https for you then, unless you define it explicitly.
您可能认为'self'localhost、本地文件系统或同一主机上的任何内容。这并不意味着其中任何一个。这意味着与定义内容策略的文件具有相同方案(协议)、相同主机和相同端口的源。通过 HTTP 为您的站点提供服务?除非你明确定义它,否则没有 https 给你。
I've used 'self'in most examples as it usually makes sense to include it, but it's by no means mandatory. Leave it out if you don't need it.
我'self'在大多数示例中都使用过,因为包含它通常是有意义的,但这绝不是强制性的。如果您不需要它,请不要使用它。
But hang on a minute!Can't I just use content="default-src *"and be done with it?
但是等一下!我不能只使用content="default-src *"并完成它吗?
No. In addition to the obvious security vulnerabilities, this also won't work as you'd expect. Even though some docsclaim it allows anything, that's not true. It doesn't allow inlining or evals, so to really, really make your site extra vulnerable, you would use this:
不。除了明显的安全漏洞之外,这也不会像您期望的那样工作。尽管一些文档声称它允许任何事情,但事实并非如此。它不允许内联或评估,因此要真正使您的网站更加脆弱,您可以使用:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
... but I trust you won't.
……但我相信你不会。
Further reading:
进一步阅读:
http://content-security-policy.com
http://content-security-policy.com
回答by Erik Hendriks
APACHE2 MOD_HEADERS
APACHE2 MOD_HEADERS
You could also enable Apache2 mod_headers, on Fedora it's already enabled by default, if you use Ubuntu/Debian enable it like this:
您还可以启用 Apache2 mod_headers,在 Fedora 上它已经默认启用,如果您使用 Ubuntu/Debian,请像这样启用它:
# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
apache2 -k graceful
On Ubuntu/Debian you can configure headers in the file
/etc/apache2/conf-enabled/security.conf
在 Ubuntu/Debian 上,您可以在文件中配置标头
/etc/apache2/conf-enabled/security.conf
#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
# 
#Header set X-Content-Type-Options: "nosniff"
#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickHymaning attacks.
# Requires mod_headers to be enabled.
#
Header always set X-Frame-Options: "sameorigin"
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Pragma "no-cache"
Header always set Expires "-1"
Header always set Content-Security-Policy: "default-src 'none';"
Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
Header always set Content-Security-Policy: "style-src 'self' www.example.com;"
Note: This is the bottom part of the file, only the last 3 entries are CSP settings.
注意:这是文件的底部,只有最后 3 个条目是 CSP 设置。
The first parameter is the directive, the 2nd are the sources to be white-listed. I've added Google analytics and an adserver, which you might have. Furthermore I found that if you have aliases, e.g, www.example.com and example.com configured in Apache2 you should add them to the white-list as well.
第一个参数是指令,第二个参数是要列入白名单的来源。我已经添加了谷歌分析和广告服务器,你可能有。此外,我发现如果您有别名,例如在 Apache2 中配置的 www.example.com 和 example.com,您也应该将它们添加到白名单中。
Inline code is considered harmful, you should avoid it. Copy all the javascripts and css to separate files and add them to the white-list.
内联代码被认为是有害的,你应该避免它。将所有 javascripts 和 css 复制到单独的文件并将它们添加到白名单。
While you're at it you could take a look at the other header settings and install mod_security
当您使用它时,您可以查看其他标头设置并安装 mod_security
Further reading:
进一步阅读:
https://developers.google.com/web/fundamentals/security/csp/
https://developers.google.com/web/fundamentals/security/csp/
回答by Mikhail Andrianov
Don't forget about the font-src it works the same as any other, but if you use fonts loaded from other origins - make sure you add it to meta tag
不要忘记 font-src 它的工作原理与其他任何一样,但是如果您使用从其他来源加载的字体 - 请确保将其添加到元标记

