vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.2k stars 26.75k forks source link

Content Security Policy (CSP) nonce's only work when using app router #61694

Open ivanvanderbyl opened 7 months ago

ivanvanderbyl commented 7 months ago

Link to the code that reproduces this issue

https://github.com/ivanvanderbyl/next-js-broken-nonce-issue

To Reproduce

Load up the reproduction app and inspect the source of these two pages:

  1. / — this uses app router and contains nonces on the scrip tags
  2. /anotherpage — this uses the pages router and does not contain nonces

Current vs. Expected behavior

According to the docs on configuring your application for CSP, adding the middleware should be all that is required, however, it fails to mention that this only works for app router and is not supported by pages router.

When using pages router:

Current behaviour: nonces are not applied to script tags that import next components. Expected: Next should detect the CSP headers in the request and apply them to the next script tags.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000
Binaries:
  Node: 21.6.1
  npm: 10.2.4
  Yarn: 1.22.19
  pnpm: 8.15.1
Relevant Packages:
  next: 14.1.1-canary.36 // Latest available version is detected (14.1.1-canary.36).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Middleware / Edge (API routes, runtime), Routing (next/router, next/navigation, next/link)

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), Vercel (Deployed)

Additional context

No response

Shani815 commented 7 months ago

@leerob I am facing this issue too, please fix it ASAP or tell me the solution how to fix it otherwise , I might have to consider migrating my entire application to App Router. While I've updated the project's versions, transitioning to App Router would require significant time and effort, including revising all existing logic. I attempted to address the problem by adding a nonce through the _document file, which successfully applied to certain scripts. However, I'm encountering issues with Tailwind styles and scripts not functioning as expected import Document, { Html, Head, Main, NextScript } from 'next/document' import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const nonce = ctx.req?.headers?.['x-nonce']
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            // eslint-disable-next-line react/jsx-props-no-spreading
            sheet.collectStyles(<App {...props} />),
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        nonce,
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }

  render() {
    const { nonce } = this.props
    return (
      <Html lang="en">
        <Head nonce={nonce} />
        <body >
          <Main />
          <NextScript nonce={nonce} />
        </body>
      </Html>
    )
  }
}
harshidw commented 4 months ago

Did you find anything @Shani815 ? I am facing the exact same problem. All the discussions about this are closed off too @leerob , migrating the application to app/ from pages/ is going to take a significant amount of time and resources, wondering if there's a better way to solve this. Bumping this up.