https://github.com/davidbuck/example-nextjs-csp-setup
A simple example showing how to get the default Next.js template working with a secure Content Security Policy (CSP)
https://github.com/davidbuck/example-nextjs-csp-setup
Last synced: 2 months ago
JSON representation
A simple example showing how to get the default Next.js template working with a secure Content Security Policy (CSP)
- Host: GitHub
- URL: https://github.com/davidbuck/example-nextjs-csp-setup
- Owner: DavidBuck
- Created: 2024-07-09T22:26:27.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2024-07-09T23:35:12.000Z (11 months ago)
- Last Synced: 2025-02-01T03:26:14.863Z (4 months ago)
- Language: CSS
- Size: 85.9 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Example NextJS CSP Setup
A simple example showing how to get the default Next.js template working with a secure Content Security Policy (CSP).
The project was created using: `$ npx create-next-app@latest`
## 1. Add a nonce-based CSP using middleware
in /middleware.js
```javascript
import { NextResponse } from 'next/server'
export function middleware(request) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' ${
process.env.NODE_ENV === "production" ? `` : `'unsafe-eval'`
};
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`;// Replace newline characters and spaces
const contentSecurityPolicyHeaderValue = cspHeader
.replace(/\s{2,}/g, ' ')
.trim()
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-nonce', nonce)
requestHeaders.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue
)
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
})
response.headers.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue
)
return response
}
```## 2. Force dynamic rendering
in /app/layout.js
```javascript
export const dynamic = "force-dynamic";
```## 3. Remove next/image inline styles
Override the default Next/Image component and remove the inline style `(style="color:transparent" )`
in /app/\_components/image.js
```javascript
import { getImageProps } from "next/image"export default function Image(props) {
const { props: nextProps } = getImageProps({
...props
})const { style: _omit, ...delegated } = nextProps
return
![]()
}
```Finally, update the imports in /app/page.js
```javascript
// import Image from "next/image";
import Image from "./_components/image";
```The CSP should now work in development and production modes without error.
`$ npm run dev`
`$ npm run build && npm run start`# References
[Middleware Setup](https://nextjs.org/docs/pages/building-your-application/configuring/content-security-policy#adding-a-nonce-with-middleware)
[Remove Next/image inline style](https://github.com/vercel/next.js/issues/45184#issuecomment-1988319088)
Issues relating to next/image, inline syles and CSP - [#61388](https://github.com/vercel/next.js/issues/61388), [#45184](https://github.com/vercel/next.js/issues/45184).