david
(David Taylor)
1
从 v3.3.0.beta1 开始,Discourse 实施了“strict-dynamic”内容安全策略 (CSP)。这将消除手动配置 CSP 的需求,并大大提高与标签管理器和广告等外部工具的兼容性。
作为站点管理员,您无需执行任何操作。更改将自动生效,您正在使用的任何外部脚本将继续正常工作。
主题无需更改。少数插件 [^1] 可能需要进行少量调整以兼容此更改(例如 1, 2)。
[^1]:技术上讲:那些通过 register_html_builder 或 erb 模板引入 <script> 元素的插件。
以前为兼容外部脚本而禁用 CSP 的论坛现在应该能够重新启用它,而不会出现任何问题或需要进行配置。
有关技术细节,请参阅此主题:
目前,仍然可以通过禁用“content security policy strict dynamic”站点设置来切换回旧系统。如果您有任何理由这样做,请告知我们!
从 v3.3.0.beta3 开始,我们将“strict-dynamic”关键字设为 CSP 的强制部分。已移除“content security policy strict dynamic”站点设置,并且“content security policy script src”站点设置已更新,仅存储有效值。
对于管理员,您应该可以在您站点的员工操作日志中找到“content security policy script src”站点设置的先前值(https://<site_url>/admin/logs/staff_action_logs?filters=%7B%22action_name%22%3A%22change_site_setting%22%2C%22action_id%22%3A3%2C%22subject%22%3A%22content_security_policy_script_src%22%7D - 将 <site_url> 替换为您站点的基础 URL)。
26 个赞
haozi
(耗子)
2
更改后,我该如何像以前一样配置 'unsafe-eval'?
1 个赞
david
(David Taylor)
3
那里没有变化——你仍然可以添加“unsafe eval”(带引号)到 content security script src 站点设置中。
3 个赞
haozi
(耗子)
4
我看到 content security script src 设置的描述说,启用 content_security_policy_strict_dynamic 将会忽略此设置,所以来这里咨询一下。
3 个赞
david
(David Taylor)
5
描述中写道:
启用 content_security_policy_strict_dynamic 时将忽略主机来源。
其中重要的部分是“主机来源”。“unsafe-inline”不是主机来源,因此它仍然受支持。
话虽如此,我完全同意这很令人困惑。鉴于 strict-dynamic 推出的成功,我们计划移除旧系统。一旦我们这样做,我们就可以自动从列表中删除所有主机来源,这样管理员就会简单得多。
5 个赞
大卫,
只是想澄清一下。
这个新系统可能适用于:
但对于使用“loadScript”调用远程脚本且包含完整远程 URL 的情况,又该如何处理呢?
如果我没记错的话,我好像找不到一种很好的方法来处理这种情况?
那么,对于这些情况,我们是否需要改用以下方法:
- 将该调用移至行内脚本 OR
- 将完整源下载为主题资源?
对于前者行内脚本的情况,我猜没有办法保证在调用脚本的元素之前加载该脚本?(就像您可以在 loadScript 之后的 .then 中做的那样)
2 个赞
david
(David Taylor)
8
strict-dynamic 应该能与通过 loadScript 加载的远程脚本配合使用。事实上,这也是我们进行此次切换的主要原因:我们不再需要预先列出每一个外部脚本的 URL。这对于运行广告的人来说尤其有利,因为广告通常会加载大量远程脚本。
您在使用 loadScript 时遇到错误了吗?
3 个赞
我看到了一些错误,但这可能不是原因。让我找个例子。
我主要是在为一次稳定的升级做准备,我知道这涉及到 loadScript 和远程脚本。
您能满足我一下,解释一下代码中用 loadScript 随机调用的远程脚本是如何被“授权”的吗?动态模式 CSP 是怎么做到的?是不是有什么神奇之处?
3 个赞
david
(David Taylor)
10
是的!
MDN 有一个很好的解释和示例。
'strict-dynamic' 源表达式指定,通过使用 nonce 或哈希明确授予标记中存在的脚本的信任,将传播给该根脚本加载的所有脚本。
因此,只要原始脚本是受信任的(通过 nonce),浏览器就允许它无限制地加载任何其他脚本。然后,由于这些脚本是受信任的,它们可以加载更多!
有一个警告,那就是脚本不能是“解析器插入”的。这可以防止 strict-dynamic 被用于 XSS 攻击。
因此,例如,这将被视为“解析器插入”并被阻止:
document.head.appendChild("<script src='https://example.com/xss-attempt.js' />");
但是,以编程方式构造脚本元素不涉及 HTML 解析,不太可能是 XSS 向量,因此是被允许的:
const script = document.createElement("script");
script.src = "https://example.com/script.js"
document.head.appendChild(script);
^^ 这基本上就是 loadScript() 的工作方式
3 个赞
很棒的链接。
好的,差不多了,谢谢!
nonce 是否也包含在 loadScript 渲染的脚本标签中?
2 个赞
david
(David Taylor)
12
不,nonce 仅包含在 Rails 渲染的原始脚本标签中(例如,核心、插件或主题脚本)。
这意味着核心/插件/主题代码是受信任的,并允许插入任何其他脚本。此处不需要 nonce - 浏览器知道是哪个脚本执行了插入,并神奇地知道它可以被信任。
4 个赞
david
(David Taylor)
拆分了此话题
14