Safari 11.0.3 无法识别内容安全策略哈希

Anu*_*nuj 4 safari content-security-policy

我有一个包含以下指令的元标记:

<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; script-src 'self' 'sha256-s5EeESrvuQPpk2bpz5I3zn/R8Au2DYB1Z+YUH9p0fUE=' 'sha256-PYYfGnkbZ44B9ZBpgv8NbP3MXT560LMfrDSas2BveJo=';">
Run Code Online (Sandbox Code Playgroud)

然后我在页面下方有 2 个内联脚本,每个脚本都应与策略中生成的 shas 之一匹配。

在 Chrome 和 Firefox 中,我没有收到任何抱怨,我的脚本按预期运行。

在 Safari 版本 11.0.3 (13604.5.6) 中,出现以下错误:

Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy
Run Code Online (Sandbox Code Playgroud)

我很困惑为什么!

不幸的是,我无法生成包含其中问题的最小可重复存储库 - 较小的示例在 Safari 中对我有用,所以它让我相信它与我的应用程序中的某些特定内容有关,可能与我拥有的第二件事有关下面试过。

任何帮助将非常感激!

我尝试过的事情:

是否支持哈希?

根据这篇 Stack Overflow 帖子Safari 发行说明,支持哈希的 CSP 2.0 已在 Safari 10 中实现

正确的字符集?

以前,我看到了一些问题,因为我正在计算基于 UTF-8 字符集的哈希值,但是在没有适当的字符集元标记的情况下将 JS 输出到浏览器。当浏览器尝试计算它们时,我的 JS 中的特殊字符被破坏并导致 shas 的差异。

我不相信这会影响我,因为 Chrome 和 Firefox 没有发现任何问题,但也许我在这里错了?

unsafe-inline Safari,然后允许哈希覆盖 Chrome 和 Firefox 中的哈希?

根据 CSP 规范,如果存在散列或随机数unsafe-inline忽略。Safari 11 也坚持这一点,所以添加unsafe-inline关键字没有效果

Anu*_*nuj 6

原来这是一个字符集问题。

我设法解决了一个最小的可重现问题(经过一些反复试验和很多运气!)并发现我的一个角色在 Safari 中渲染前后具有不同的 sha。

在 Safari 中渲染之前,角色如下:

在 Safari 渲染角色之前

在 Safari 渲染了这个角色之后,它是这样的(甚至在代码的源代码中):

Safari 渲染角色后

奇怪的是,Chrome 和 Firefox 都没有这个问题,所以要么必须是 Safari 在字符呈现后对其进行规范化,要么是sha256浏览器之间计算哈希值的时间不同。

解决方案是在 UglifyJS 中关闭字符压缩,以便字符保持原样,\uF900而不是被压缩为上图中的单个字符。

我在 webpack.config.js 文件中使用以下选项实现了这一点:

new UglifyJsPlugin({
    uglifyOptions: {
        output: {
            // necessary to stop the minification of escaped unicode sequences into their actual chars.
            // some unicode breaks CSP checks in safari
            ascii_only: true,
        },
    },
}),
Run Code Online (Sandbox Code Playgroud)

我已经向 Apple 报告了这个问题,看看他们是否会考虑解决这个问题。