【问题标题】:Content Security Policy hash not recognized by Safari 11.0.3Safari 11.0.3 无法识别内容安全策略哈希
【发布时间】:2018-02-22 23:03:46
【问题描述】:

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

<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; script-src 'self' 'sha256-s5EeESrvuQPpk2bpz5I3zn/R8Au2DYB1Z+YUH9p0fUE=' 'sha256-PYYfGnkbZ44B9ZBpgv8NbP3MXT560LMfrDSas2BveJo=';">

然后,我在页面下方有 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

我很困惑为什么!

不幸的是,我无法针对其中的问题生成最低限度的可重现回购 - 较小的示例适用于我的 Safari,因此它让我相信它与我的应用程序中的特定内容有关,可能与第二个有关我在下面尝试过的东西。

任何帮助将不胜感激!

我尝试过的事情:

是否支持哈希?

根据this Stack Overflow postSafari release notes,支持哈希的CSP 2.0 已在Safari 10 中实现

正确的字符集?

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

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

unsafe-inline 用于 Safari,然后允许哈希在 Chrome 和 Firefox 中覆盖它?

根据 CSP 规范,unsafe-inlineignored if a hash or nonce is present。 Safari 11 也坚持这一点,所以添加 unsafe-inline 关键字没有效果

【问题讨论】:

    标签: safari content-security-policy


    【解决方案1】:

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

    我设法得到了一个最小的可重现问题(经过一些试验和错误,以及很多运气!)并发现我的一个角色在 Safari 中渲染之前和之后具有不同的 sha。

    在 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,
            },
        },
    }),
    

    我已将此问题报告给 Apple,看看他们是否会考虑解决此问题。

    【讨论】:

    • 我遇到了类似的问题,在渲染/哈希计算期间,Safari 将不间断空格字符替换为正常空格。为 minimiser 插件打开 ascii_only 输出模式可以解决问题
    • @AlexeyGavrilov 和 Anuj - 针对上述问题报告了任何错误?如果可以,请在此处添加链接。
    【解决方案2】:

    另一种解决方案是确保脚本中的字符串规范化。这可以在 JavaScript 中使用String.normalize 来实现。

    规范化确保每个 Unicode 字符都以其规范 (NFC) 形式表示,这似乎使 Safari 中的 CSP 哈希比较起作用。因此,如果您正在处理可能使用重音符号、非拉丁脚本等的任何类型的文本,最好对字符串进行规范化。

    【讨论】:

      猜你喜欢
      • 2018-06-05
      • 2016-03-24
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      相关资源
      最近更新 更多