内容安全策略如何运作?

时间:2015-05-16 20:22:48

标签: javascript html security http-headers content-security-policy

我在开发者控制台中收到了一堆错误:

  

拒绝评估字符串

     

拒绝执行内联脚本,因为它违反了以下内容安全策略指令

     

拒绝加载脚本

     

拒绝加载样式表

这是怎么回事?内容安全策略如何运作?如何使用file:// HTTP标头?

具体来说,如何......

  1. ...允许多个来源?
  2. ...使用不同的指令?
  3. ...使用多个指令?
  4. ...处理端口?
  5. ...处理不同的协议?
  6. ...允许<style>协议?
  7. ...使用内联样式,脚本和代码<script>eval()
  8. ...允许'self'
  9. 最后:

    1. {{1}}究竟是什么意思?

2 个答案:

答案 0 :(得分:448)

Content-Security-Policy元标记允许您定义可以加载资源的位置,从而阻止浏览器从任何其他位置加载数据,从而降低XSS攻击的风险。这使攻击者更难将恶意代码注入您的网站。

我撞到了一堵砖墙,试图找出我为什么一个接一个地得到CSP错误,并且似乎没有任何关于它如何工作的简明扼要的指示。所以这是我尝试简要解释CSP的一些点,主要集中在我发现难以解决的问题上。

为简洁起见,我不会在每个样本中写下完整的标签。相反,我只会显示content属性,因此显示content="default-src 'self'"的示例意味着:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

<强> 1。如何允许多个来源?

您可以在指令后将源列出为空格分隔列表:

content="default-src 'self' https://example.com/js/"

请注意,特殊之外的参数没有引号,例如'self'。此外,指令后面没有冒号(:)。只是指令,然后是一个以空格分隔的参数列表。

隐式允许低于指定参数的所有内容。这意味着在上面的示例中,这些将是有效的来源:

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

然而,这些无效:

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

<强> 2。如何使用不同的指令,它们各自做什么?

最常见的指令是:

  • default-src加载javascript,图片,CSS,字体,AJAX请求等的默认策略
  • script-src定义了javascript文件的有效来源
  • style-src定义了css文件的有效来源
  • img-src定义了有效的图片来源
  • connect-src定义了XMLHttpRequest(AJAX),WebSockets或EventSource的有效目标。如果尝试连接到此处不允许的主机,则浏览器将模拟400错误

还有其他人,但这些是你最需要的。

第3。如何使用多个指令?

您可以通过以分号(;)终止它们来定义一个元标记内的所有指令:

content="default-src 'self' https://example.com/js/; style-src 'self'"

<强> 4。如何处理端口?

除了默认端口之外的所有内容都需要通过在允许的域之后添加端口号或星号来明确允许:

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

上述结果将导致:

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

正如我所提到的,您还可以使用星号来明确允许所有端口:

content="default-src example.com:*"

<强> 5。如何处理不同的协议?

默认情况下,只允许使用标准协议。例如,要允许WebSockets ws://,您必须明确允许它:

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports

<强> 6。如何允许文件协议file://

如果您尝试将其定义为此类,则无效。相反,您将允许使用filesystem参数:

content="default-src filesystem"

<强> 7。如何使用内联脚本和样式定义?

除非明确允许,否则您不能使用内联样式定义,<script>标记内的代码或onclick等标记属性。你这样允许他们:

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

您还必须明确允许内联的base64编码图像:

content="img-src data:"

<强> 8。如何允许eval()

我相信很多人会说你没有,因为'eval是邪恶的',并且最有可能导致世界即将结束。那些人会错的。当然,你可以使用eval将主要漏洞打入你网站的安全性,但它具有完全有效的用例。你只需要聪明地使用它。你允许这样:

content="script-src 'unsafe-eval'"

<强> 9。 'self'究竟是什么意思?

您可以将'self'表示localhost,本地文件系统或同一主机上的任何内容。它并不意味着任何这些。它意味着具有与定义内容策略的文件相同的方案(协议),相同主机和相同端口的源。通过HTTP服务您的站点?除非您明确定义,否则暂无https。

我在大多数示例中都使用了'self',因为包含它通常是有意义的,但它绝不是强制性的。如果你不需要,请把它拿出来。

但请等一下!我不能只使用content="default-src *"并完成它吗?

没有。除了明显的安全漏洞之外,这还会使它无法正常运行。即使some docs声称它允许任何事情,但事实并非如此。它不允许内联或遗漏,所以真的,真的,让你的网站更加脆弱,你会使用这个:

content="default-src * 'unsafe-inline' 'unsafe-eval'"

......但我相信你不会。

进一步阅读:

http://content-security-policy.com

http://en.wikipedia.org/wiki/Content_Security_Policy

答案 1 :(得分:12)

APACHE2 MOD_HEADERS

你也可以在Fedora上启用Apache2 mod_headers,默认情况下它已经启用了,如果你使用Ubuntu / Debian这样启用它:

# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
apache2 -k graceful

在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 clickjacking 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;"

注意:这是文件的底部,只有最后3个条目是CSP设置。

第一个参数是指令,第二个参数是白名单。我添加了您可能拥有的Google分析和广告服务器。此外,我发现如果您有别名,例如,在Apache2中配置了www.example.com和example.com,您也应该将它们添加到白名单中。

内联代码被认为是有害的,你应该避免它。将所有javascripts和css复制到单独的文件中,并将它们添加到白名单中。

当你在它时,你可以看看其他标题设置并安装mod_security

进一步阅读:

https://developers.google.com/web/fundamentals/security/csp/

https://www.w3.org/TR/CSP/