next.jscontent-security-policy

Nextjs preloaded scripts blocked with strict CSP


I am trying to set up strict CSP in my next app based on the next.js example. In my _document.js I have the following:

const cspHashOf = (text) => {
  const hash = crypto.createHash('sha256')
  hash.update(text)
  return `'sha256-${hash.digest('base64')}'`
}

let cspStr = ''
for (let k in csp) {
  cspStr += `${k} ${csp[k]}; `
}

...

    render() {
    const nonce = crypto.randomBytes(8).toString('base64')

    let csp = {
      'object-src': "'none'",
      'base-uri': "'self'",
      'script-src': `'nonce-${nonce}' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http: ${cspHashOf(
        NextScript.getInlineScriptSource(this.props)
      )}`,
    }

    let cspStr = ''
    for (let k in csp) {
      cspStr += `${k} ${csp[k]}; `
    }

    return (
      <Html>
        <Head>
          <meta httpEquiv="Content-Security-Policy" content={cspStr} />
          ...
        </Head>
        <body>
          ...
          <NextScript nonce={nonce} />
        </body>
      </Html>
    )

In the rendered page, I have all these preloaded chunks coming from Next which are getting blocked

<link rel="preload" href="/_next/static/chunks/8be9d4c0d98df170721d8fe575c2a4bcd5b2fbe4.e7c8a9ea6074f4dcaa51.js" as="script">
<link rel="preload" href="/_next/static/chunks/863050a7585a2b3888f2e4b96c75689f1ae4a93d.a73c594ed7ed04a682dc.js" as="script">
<link rel="preload" href="/_next/static/chunks/be8560b560b3990e61cbef828a20e51dc9370d83.4acbf8ef4e1b51b0bc0f.js" as="script">
<link rel="preload" href="/_next/static/chunks/be8560b560b3990e61cbef828a20e51dc9370d83_CSS.6164c81b6ed04bb13dbd.js" as="script">

How do I prevent them from being blocked?


Solution

  • I was eventually able to resolve this by also passing the nonce as a prop to Head

    <Head nonce={nonce}>
    

    The documentation around this from Next.js is non-existent! I'd love if anyone finds it to share the link