如何使用 SRI 哈希和“onload”属性

Posted

技术标签:

【中文标题】如何使用 SRI 哈希和“onload”属性【英文标题】:How to work with SRI hash and "onload" attribute 【发布时间】:2021-01-06 19:29:17 【问题描述】:

按照 Google Lighthouse 的建议为我的网站获得更快的响应,我正在使用这个技巧来加载字体:

<link as="style"
  href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&amp;display=swap"
  onload="this.onload=null;this.rel='stylesheet'"
  rel="preload">

但由于我严格的 CSP 规则,它失败了,我不知道如何为这个“onload”属性添加 sha384 哈希:/

我尝试像这样获取 onload 内容哈希:

echo "this.onload=null;this.rel='stylesheet'" | openssl dgst | openssl enc -base64 -A

输出:npWtxZLLH7z2/zORM47igyJ5eTYuOl9qxzn4A632S7yMmMKBDHhL5ZHC6eBSxc/C

然后我将它添加到 CSP SRI 列表中并刷新,但它失败了:

拒绝执行内联事件处理程序,因为它违反了 以下内容安全策略指令:“script-src 'strict-dynamic' '[...其他 SRI 哈希列表...]' sha384-npWtxZLLH7z2/zORM47igyJ5eTYuOl9qxzn4A632S7yMmMKBDHhL5ZHC6eBSxc/C 'unsafe-inline' http: https:"。请注意,如果 源列表中存在散列值或随机数值。

如何在不授权所有内联脚本的情况下允许这个内联“onload”小脚本? 为什么我的 SRI 在添加时不起作用? :(

谢谢!

【问题讨论】:

【参考方案1】:

为什么我的 SRI 在添加时不起作用? :(

style-src 指令的示例中解释了 here。跟script-src的情况一样。

如何在没有授权的情况下允许这个内联“onload”小脚本 内联脚本?

在topic 中将“load”的内联事件处理程序移动到单独的脚本中,例如“click”。然后可以通过'nonce-value'或'sha256/sha384/sha512-value'来允许。

更新:

我希望明确更改要做(将内联处理程序移动到单独的脚本):

<link as="style" id="fonts"
  href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&amp;display=swap"
  rel="preload">

<script nonce="sever_generated_value"> // if 'nonce-value' used.
  // Or just calculate hash sha256 (or sha384/512) of this script
  // and insert it into 'script-src' as 'sha256-calculated_value' 
  fonts.addEventListener("load", function() 
     this.onload=null;
     this.rel='stylesheet';
     );
</script>

'nonce-value'/'hash-value' 可以允许这种单独的内联脚本。

PS:请注意,内容安全策略不支持通过 SRI 为 external 样式表提供“哈希值”。仅支持内置 &lt;style&gt;...&lt;/style&gt;。对于脚本,“哈希值”is supported for both:内置&lt;script&gt;...&lt;/script&gt; 和外部&lt;script src='...' integrity='hash_here'&gt;

【讨论】:

好的,谢谢;按照当前的 SRI 草案,我认为这是有道理的。主要的“资源”是获取的样式,而不是属性的内容。但是,即使是官方草案也说它适用于 我已经稍微扩展了我的答案以避免误解或误导。 SRI 独立于 CSP 独立工作,但 CSP 可以使用 integrity= 属性通过 'hash-nonce' 允许 &lt;script src=&gt;&lt;link href= 不受 CSP 支持,但可以用于 SRI 检查。

以上是关于如何使用 SRI 哈希和“onload”属性的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ScriptBundle for .NET MVC (4.7.2) 应用程序中包含 SRI 哈希?

SRI 哈希不是预期的

为啥我不能使用 SRI 从本地计算机 (file:///) 加载文件?

是否可以将 SRI 用于 recurly.js cdn?

如何展平哈希,使每个键成为唯一值?

如何按日期(范围键)查询 DynamoDB,没有明显的哈希键?