正确使用哈希与内容安全策略(CSP)

3

我正在尝试在内容安全策略中使用哈希...

以下是我的控制台中出现的两个错误示例:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' apis.google.com cdn.iubenda.com cdnjs.cloudflare.com www.googletagmanager.com". Either the 'unsafe-inline' keyword, a hash ('sha256-oKmCrr+GWRARSXYeVJshOWETr0oqOtt73CNO8efpujQ='), or a nonce ('nonce-...') is required to enable inline execution.

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' apis.google.com cdn.iubenda.com cdnjs.cloudflare.com www.googletagmanager.com". Either the 'unsafe-inline' keyword, a hash ('sha256-pS4Uy3ilo+JLn8IadtJGfyO9z7jqIrGUONfEUDLxoPk='), or a nonce ('nonce-...') is required to enable inline execution.

这是相应的内容安全策略指令:

add_header Content-Security-Policy "default-src 'self'; script-src 'self' apis.google.com cdn.iubenda.com cdnjs.cloudflare.com www.googletagmanager.com; style-src 'self' fonts.googleapis.com; img-src 'self' cdn.shortpixel.ai secure.gravatar.com; font-src 'self' fonts.googleapis.com fonts.gstatic.com";

特别是在这个例子中:

script-src 'self' apis.google.com cdn.iubenda.com cdnjs.cloudflare.com www.googletagmanager.com;

根据我阅读的哈希方式指南,我应该能够像在控制台中一样将哈希值添加到指令中...

最简单的生成哈希值的方法是打开开发者工具控制台,它会输出您的脚本的期望哈希值。

但是,如果我修改指令以包含哈希(如下所示),我在控制台中仍然会收到相同的错误(显然哈希值不同)。

script-src 'self' apis.google.com cdn.iubenda.com cdnjs.cloudflare.com www.googletagmanager.com 'sha256-oKmCrr+GWRARSXYeVJshOWETr0oqOtt73CNO8efpujQ=';

正确的CSP指令哈希方式是什么?同一指令为何会有多个错误,这是否基本上为每个指定域名都有一个错误?应该使用一个哈希覆盖所有指定的域名吗?

我不太确定自己该如何处理这个问题。

1个回答

0
从我阅读 content-security-policy.com/hash/ CSP 指南中了解到,我应该能够将哈希作为我的控制台添加到指令中...

是的,这只是在“理论上”有效,实际操作更加困难。是的,Google Chrome 计算哈希值,但您需要仔细阅读错误消息以确定实际被阻止的内容:inline scriptjavascript: navigationinline event handler。因为每个都有自己的修复方式。

- 内联脚本可以通过 'sha256-VALUE' 令牌直接允许。
- 要允许 javascript: navigation 和内联事件处理程序,您需要使用带有 'unsafe-hashes' 的 'sha256-VALUE' 令牌。目前,并非所有浏览器都支持 javascript: navigation 的 'unsafe-hashes'
但是,如果我修改我的指令以包括哈希(如下面的示例),我仍然会在控制台中收到相同的错误(显然哈希不同)。
为什么你停了?我看到你使用了www.googletagmanager.com(GTM),你认为GTM只有一个内联脚本吗?你允许父脚本,它开始加载子脚本,因此您需要为两者都添加哈希。
您可以使用父脚本哈希+“strict-dynamic”令牌来允许所有子脚本,但目前在Safari中无法正常工作。
最终,您将获得所有内联脚本的许多哈希。糟糕的是,GTM和其他人可能会时不时更改其内联脚本的内容,因此您必须添加新的哈希并删除过时的哈希。但您不知道哪个哈希属于哪个脚本。
因此,最好的方法是对于任何内联脚本都使用'nonce-value',尤其是因为GTM 将'nonce'分配给所有内联脚本,除了自定义HTML标签。对于自定义HTML标签(如果使用),您可以使用哈希值,因为这些脚本在您的控制之下。
在决定如何更轻松可靠地允许它们之前,最好手动调查所有内联脚本。

提示:对于 CSP 来说,GTM 是一个难题,因为 GTM 可以用于注入一系列内联/外部脚本。如果在“自定义 HTML 标签”中使用自定义 JavaScript 变量名称,则需要允许 'unsafe-eval'。


您可以测试您的 GTM ID,了解它加载了哪些附加脚本以及哪种 CSP 足够保护它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接