标签中的
Content-Security-Policy
允许您定义资源可以从哪里加载,防止浏览器从任何其他位置加载数据,从而降低
跨站脚本攻击风险。这使得攻击者更难将恶意代码注入到您的站点中。为了简洁起见,示例中我不会在每个样本中写完整的标记。相反,我只会展示其
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. 我该如何使用多个指令?
你可以在一个 meta 标签中定义所有的指令,并通过分号(;
)来终止它们:
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. 我该如何处理不同的协议?
默认情况下,只允许使用标准协议。例如,要允许WebSocket 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 *"
就搞定了吗?
不行。除了明显的安全漏洞外,这也无法按照你预期的工作。虽然一些文档声称它允许所有内容,但事实并非如此。它不允许内嵌或评估,因此要使你的网站真正变得极度脆弱,你应该使用以下代码:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
......但我相信你不会这样做。
进一步阅读:
http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy