Generate random nonce one every HTTP page load #21587
-
Describe the feature you'd like to request Generate random value nonce (base64 or sha256) using an anonymous function every time user visits the appsite. Currently if defining the CSP in next.config.js with nonce, that nonce value is generated ONCE when running the app. Describe the solution you'd like In next.config.js have a property that takes a function and returns a string (base64 nonce value). This function can be called every time a user visits the appsite. That nonce is passed to Content Security Policy when defining headers. Also that nonce can be accessed in _document.tsx . To make sure the nonce value is set properly Ex: const { v4 } = require('uuid');
const crypto = require('crypto');
module.exports = {
nonceGenerator: () => {
const hash = crypto.createHash('sha256');
hash.update(v4());
return hash.digest('base64');
},
async Headers() {
returns [
{
source: '/.(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: 'script-src nonce-{generatedNonce};'
}
]
}
]
}
} Than you can access the generated nonce in _document.jsx import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import getConfig from 'next/config'
import { ServerStyleSheets } from '@material-ui/core/styles';
const { generatedNonce } = getConfig();
export default class MyDocument extends Document {
render(): JSX.Element {
return (
<Html lang='en'>
<Head nonce={generatedNonce}>
<meta property='csp-nonce' content={generatedNonce} />
{/* <meta httpEquiv='Content-Security-Policy' content={csp} /> */}
</Head>
<body>
<Main />
<NextScript nonce={generatedNonce} />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with server-side generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
};
}; Describe alternatives you've considered I have looked at and tried the CSP example https://github.com/vercel/next.js/blob/master/examples/with-strict-csp/pages/_document.js But I found an issue with this approach. The CSP is being applied potentially client side and not when the SSR is taking place. Since it's not there, I'm guessing CSP with the nonce is being applied client side. That could be security issue. I'm aware you can create using your own custom server. But that removes the optimizations the default NextJS server has. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
It looks like that approach uses a meta tag instead of an HTTP header, but the meta tag is generated server side. This MDN article says that's ok: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP |
Beta Was this translation helpful? Give feedback.
-
Hey folks, wanted to swing back here with an update. After digging through many different issues and discussions, I've made a new page in the documentation (PR) specifically for Content Security Policy and nonces. This docs page:
Further, we've patched some bugs and made improvements to Really hope this helps out, thank you all 🙏 I'll be closing this discussion out. To continue the discussion, please go here. |
Beta Was this translation helpful? Give feedback.
Hey folks, wanted to swing back here with an update. After digging through many different issues and discussions, I've made a new page in the documentation (PR) specifically for Content Security Policy and nonces. This docs page:
nonce
with Middlewarenonce
in a route withheaders()
unsafe
nonce
Middleware from running on prefetches / static assetsFurther, we've patched some bugs and made improvements to
nonce
handling in Next.js that will be available in the latestcanary
version (for those of you time traveling from the future, upgrade to Next.js 13.5). We also …