NextJS 内容安全策略 (CSP)

16

我目前正在为一个使用Next.js制作的生产应用程序创建内容安全策略(CSP)。虽然我已经找到了有信赖的文档来实现CSP,但我有一些问题需要确保正确处理。

问题#1:我已经阅读过在HTTP标头中设置安全策略更可取的信息。但是,我无法找到一种方法来在生产环境中传递内联样式的'nonce'属性,而不使用其他的方式。https://nextjs.org/docs/advanced-features/security-headers

问题#2:我看到其他开发者将他们的CSP注入到自定义文件中(“./pages/_document.js”)。我不愿使用此方法,因为我听说元标记CSP可以轻易绕过。 https://github.com/vercel/next.js/tree/canary/examples/with-strict-csp

我的问题:

  1. 有没有办法在“next.config.js”中使用标头配置来使用“nonce”? 如果有,如何做?
  2. 如果Next.js自动清理用户输入,那么在生产中指定“unsafe-inline”样式是否存在安全问题?我还应该提到,在我的API中,我也会清理所有mongo数据库查询。
  • 描述问题#2中的meta标签方法是否有类似于HTTP标头方法一样安全的特点?
  • 您推荐我采用什么方法使我的Web应用程序的CSP尽可能强大?
  • 祝一切顺利, -Sam


    我们现在有关于处理随机数和内容安全策略的官方文档:https://nextjs.org/docs/app/building-your-application/configuring/content-security-policy - leerob
    1个回答

    3
    NextJS有两种预渲染模式:静态网站生成(SSG)和服务器端渲染(SSR)。第一种模式没有办法更新HTML代码中的nonce='value',但是在SSG中,你可以通过./pages/_document.tsx传递一个'nonce'属性来为内联样式和脚本添加'nonce'属性。
    请参考CSP头部示例meta标签CSP示例
    关于问题:
    1. 我认为使用next.config.js是可能的,例如next-safe包将nextSafe()函数添加到此文件中以设置许多标头。
    const nextSafe = require('next-safe')
    const isDev = process.env.NODE_ENV !== 'production'
    module.exports = {
      async headers () {
        return [
        {
          source: '/:path*',
          headers: nextSafe({ isDev }),
        },
          ]
      },
    }
    

    要将'nonce'设置到CSP头中,您可以按照以下方式编写自己的函数。要将'nonce'属性设置到样式中,您可以使用_document.tsx渲染器。
    在生产环境中为样式指定'unsafe-inline'不会造成安全问题。例如,https://accounts.google.com页面允许内联样式(它甚至没有style-src/default-src指令,但仍然仔细控制脚本)。
    将CSP设置在HTTP标头中是可取的,但这并不意味着meta标签中的CSP易于被绕过。只要CSP在meta标签中有一些限制,如果您不使用已被限制的功能,那么可以安全地使用meta标签来传递CSP。
    您可以无限地加强保护,耗费大量时间和资源。只需遵循主要原则"保护对象不应比保护更昂贵"即可。

    谢谢您的回复。我应该提到我正在使用“next-secure-headers”。我不清楚您对我的第一个问题的回答。您说:“要将'nonce'设置到CSP标头中,您可以以这种方式编写自己的函数。”您是说可以通过“next.config.js”传递一个函数,该函数将在“_document.tsx”中可访问吗?此外,我知道“unsafe-inline”不像脚本那样存在安全问题。但是,我想确保任何人都无法将自己的CSS注入页面。在Next.js中指定“unsafe-inline”会使我容易受到攻击吗? - Sam Morgan
    (1) 我想说的是,next.config.js 看起来可以从全局命名空间调用一个函数。在这种情况下,该函数将可以访问 'nonce' 值。您可以在 next-safe 包代码中进行检查。(2) 当然,在 style-src 中的 'unsafe-inline' 技术上允许注入内联 CSS。但是,没有脚本注入,基于 CSS 的无脚本 XSS 的范围非常狭窄。因此,更多的关注点放在脚本而不是样式上。 - granty
    官方代码示例链接在答案中:CSP头文件示例meta标签CSP示例。你看过这些了吗? - granty
    是的,我看到了。我试图在标头中使用“nonce”而不是元标记方法,但我想这是不可能的。似乎绝对没有办法使用next.config.js与将传递给DOM的nonce值。这些示例在客户端创建哈希并在每个应用程序页面上插入CSP元标记。我唯一想避免的是在生产中为样式使用“unsafe-inline”。如果您说这对于Next JS应用程序不构成风险,我相信您并将坚持使用标头方法。感谢您的所有帮助。 - Sam Morgan
    嘿,Sam,你找到了CSP的好解决方案吗?我也在为同样的问题苦恼。 - undefined
    显示剩余3条评论

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接