带有哈希的 CSP script-src strict-dynamic 正在阻止主机域

CSP script-src strict-dynamic with hash is blocking host domain

我有一个反应(创建反应应用程序,未弹出)前端,node/express 后端具有以下 csp 配置:

app.use(
  helmet.contentSecurityPolicy({
directives: {
      'script-src': [
        "'self'",
        "'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='",
        "'sha256-10e801rrdN2Gq8YctvySwnSlugHJX+Xjgx1mhmij72w='",
        "'sha256-e89fobGAetuB/6VgXYgfYEJo7toSqmridYOdrJoE6LU='",
        "'strict-dynamic'",
        'http:',
        'https:',
        "'unsafe-inline'",
      ],
      'object-src': ["'none'"],
      'base-uri': ["'none'"],
    },
  })
)

您在此处看到的哈希是在以前的 csp 错误中提供的。我找到了这三个脚本,并使用哈希工具验证了上述指令中的哈希属于这三个脚本。

当我使用此配置发布到 heroku 时,我用 https://csp-evaluator.withgoogle.com/ 测试了 url,它说一切正常。

但是我的站点不会呈现,并且在 chrome devtools 中我收到以下 CSP 错误,“您站点的内容安全策略阻止了一些资源”:

如您所见,它阻止了来自主机 url 的资源,而不是来自第三方的资源。

错误中的脚本如下所示,在 index.html:

    <script src="/static/js/runtime-main.11477cd6.js"></script>
    <script src="/static/js/7.e1d80075.chunk.js"></script>
    <script src="/static/js/main.c7392c1f.chunk.js"></script>

我访问了 link 提供的错误,“查看如何设置严格的 CSP”并按照他们的说明(不折不扣地)针对基于散列的 CSP,只有当那不起作用时,我添加了 'self'、'http:'、'https:' 和 'unsafe-inline'。我 认为 那些可以留在那儿,它们似乎不会造成任何问题。我什至尝试添加实际域,但没有任何改变。

我已经设置了 INLINE_RUNTIME_CHUNK=false 环境变量,这是 CRA 应用程序(也在 heroku 配置中)所需的,它修复了一些以前的(不同的)问题,但现在正在发生这种情况。

我认为问题可能在于散列是根据脚本的路径生成的,字面意思是 src="/path/file.js" 而不是该文件中的实际脚本,所以我对这三个脚本进行散列并将这些散列添加到指令。还是不行。

此外,我注意到使用 nonces,示例显示带有添加的随机数 属性 的脚本标记,例如 <script src="something.js" nonce="noncerandom"></script> 所以,我尝试将 'integrity' 与散列值一起使用脚本,(不是文件路径。)现在,没有任何错误,但也没有任何渲染。根 <div>s.

里面什么都没有

我放弃!请帮忙。我已经阅读了至少 50 个关于 Whosebug 的相关问题,遵循评论和答案中推荐的每个 link,根据 heroku 重写和重新部署 106 次。 (None 的问题发生在本地主机上,所以我每次都必须重新发布。)

事实证明,必须同时添加 script-src 哈希值和 <script> 标签完整性值,即使使用像头盔这样的中间件也是如此。我的错误印象是您不需要费心更新 <script> 标签,除非您在 <meta> 标签中设置 headers,但事实上,它们在任何情况下都是必需的。

这意味着您必须在每次前端构建后手动替换所有这些哈希值,因为这些脚本会发生变化。没什么大不了的,只是在开发过程中需要额外的手动操作。某处可能有相应的软件包。

这是我的头盔配置最终的样子:

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      'img-src': [
        "'self'",
        'data:',
        'flagcdn.com',
        'upload.wikimedia.org',
        'openweathermap.org',
        'hereapi.com',
        'js.api.here.com',
      ],
      'default-src': ["'none'"],
      'script-src': [
        "'sha256-gpDxdDuBGxxl88r6aymWROliaETfsyODwU6dpFZyIUU='",
        "'sha256-33dcmxHc726AphEOtauUa39NPzHtsEPzEAX8PKd8NU0='",
        "'sha256-vqol01UCQbQtIbFsadt22MWtP/EzXBhlXJVTdE3Z0Nk='",
        "'sha256-vnJfeIr7hNIEwFqAV/GfKdJDn1SeGTUHl87WXU7cOxA='",
        "'strict-dynamic'",
      ],
      'object-src': ["'none'"],
      'base-uri': ["'none'"],
      'connect-src': [
        'sheltered-scrubland-08732.herokuapp.com',
        'https://*.here.com:*',
        'https://*.hereapi.com:*',
        'blob:',
      ],
      'worker-src': ["'self'", 'blob:'],
      'manifest-src': ['https://sheltered-scrubland-08732.herokuapp.com'],
      //  'require-trusted-types-for': [`'script'`], // cannot use. 'script' value requires further specifications which are a mystery to solve some other time.
    },
  })
)

这里是 index.html 中的 <script> 标签:

   <script
      src="/static/js/runtime-main.11477cd6.js"
      integrity="sha256-gpDxdDuBGxxl88r6aymWROliaETfsyODwU6dpFZyIUU="
    ></script>
    <script
      src="/static/js/7.e1d80075.chunk.js"
      integrity="sha256-33dcmxHc726AphEOtauUa39NPzHtsEPzEAX8PKd8NU0="
    ></script>
    <script
      src="/static/js/main.c7392c1f.chunk.js"
      integrity="sha256-vqol01UCQbQtIbFsadt22MWtP/EzXBhlXJVTdE3Z0Nk="
    ></script>

为了获得这些哈希值,我将 runtime-main.11477cd6.js 等中的实际源代码复制并粘贴到 https://report-uri.com/home/hash 中。这是我从未在任何地方读到过的东西,但对我来说,用文件路径的 <script> 标签进行散列是没有意义的。散列文件路径有什么意义???在不止一篇文章中,他们实际上建议使用 devtools csp 错误消息中提供的哈希值,我发现这些消息是由文件路径脚本标签生成的,这可能就是为什么一开始没有任何效果的原因。嗯。