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' 表示本地主机、本地文件系统或同一主机上的任何内容。这并不意味着其中任何一个。这意味着源与定义内容策略的文件具有相同的方案(协议)、相同的主机和相同的端口。通过 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