I am currently making a Content Security Policy (CSP) for a production application made with Next.js. While I have found trustworthy documentation for implementing a CSP with the framework, there are a couple of concerns that I want to make sure are addressed correctly.
Issue #1: I have read that security policies set in HTTP headers are preferable. However, I cannot find a way to pass a 'nonce' attribute for inline styles in production using this approach. https://nextjs.org/docs/advanced-features/security-headers
Issue #2: I've seen other examples where developers inject their CSP in the custom document("./pages/_document.js"). I am hesitant to use this approach because I hear meta-tag CSPs are easily bypassable. https://github.com/vercel/next.js/tree/canary/examples/with-strict-csp
My Questions:
All the best, -Sam
NextJS has 2 pre-rendering mode: Static Site Generation(SSG) and Server-Side Rendering(SSR). The first one has no way to update nonce='value' in the HTML code, but when using SSR you can pass a 'nonce' attribute for inline styles and scripts using ./pages/_document.tsx.
See an example for CSP header and meta tag CSP example.
Re Questions:
next.config.js is possible, for example next-safe package adds a nextSafe() function into this file to set a lot of headers:const nextSafe = require('next-safe')
const isDev = process.env.NODE_ENV !== 'production'
module.exports = {
async headers () {
return [
{
source: '/:path*',
headers: nextSafe({ isDev }),
},
]
},
}
To set 'nonce' into CSP header you can craft your own function in this way. To set 'nonce' attribute into styles you can use _document.tsx renderer.
Specifying 'unsafe-inline' for styles in production is not a security issue. For example https://accounts.google.com page allows inline styles (it even does not have style-src/default-src directives but it carefully controls scripts).
Setting CSP in HTTP headers is preferable but this does not mean that CSP in meta tag is easily bypassable. Just CSP in meta tag has some restrictions and if you do not use features that have been restricted you can safely use meta tag to delivery CSP.
You can strengthen protection indefinitely, spending a lot of time and resources. Just follow the main principle "protection should not be more expensive than the protected object".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With