The Content-Security-Policy
元标记可以让您降低风险XSS http://en.wikipedia.org/wiki/Cross-site_scripting通过允许您定义可以从何处加载资源来防止浏览器从任何其他位置加载数据来攻击。这使得攻击者更难将恶意代码注入您的网站。
我把头撞在砖墙上,试图弄清楚为什么我会一次又一次地遇到 CSP 错误,但似乎没有任何简洁、清晰的说明来说明它是如何工作的。所以这是我尝试解释的some简要介绍一下 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/"
请注意,除了参数之外,参数周围没有引号special那些,比如'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
error
还有其他的,但这些是您最可能需要的。
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. 如何处理不同的协议?
默认情况下,仅允许标准协议。例如允许 WebSocketsws://
你必须明确允许它:
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 在站点的安全性上打出重大漏洞,但它具有完全有效的用例。您只需要聪明地使用它即可。你允许它像这样:
content="script-src 'unsafe-eval'"
9. 到底是什么'self'
mean?
你可能会采取'self'
表示本地主机、本地文件系统或同一主机上的任何内容。这并不意味着任何一个。这意味着源与定义内容策略的文件具有相同的方案(协议)、相同的主机和相同的端口。通过 HTTP 为您的站点提供服务?那么你就没有 https 了,除非你明确定义它。
我用过'self'
在大多数示例中,因为包含它通常是有意义的,但它绝不是强制性的。如果不需要,请将其保留。
但请稍等!我不能只使用content="default-src *"
就这样结束了吗?
不。除了明显的安全漏洞之外,这也不会像您期望的那样工作。虽然一些文档 http://content-security-policy.com/声称它允许任何事情,但事实并非如此。它不允许内联或评估,因此要真正使您的网站更加容易受到攻击,您可以使用以下命令:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
...但我相信你不会。
进一步阅读:
http://content-security-policy.com http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy http://en.wikipedia.org/wiki/Content_Security_Policy