You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: Add docs on CSP and nonce generation (#54601)
There's been some confusion on the correct way to add a `nonce`, so took the opportunity here to:
- Add a new docs page for Content Security Policy
- Explained how to generate a `nonce` with Middleware
- Showed how to consume the `nonce` in a route with `headers`
- Updated the `with-strict-csp` example
- Update the `nonce` error message page
- Backlinked to the new page in a few places in the docs
{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
11
+
12
+
[Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) is important to guard your Next.js application against various security threats such as cross-site scripting (XSS), clickjacking, and other code injection attacks.
13
+
14
+
By using CSP, developers can specify which origins are permissible for content sources, scripts, stylesheets, images, fonts, objects, media (audio, video), iframes, and more.
A [nonce](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) is a unique, random string of characters created for a one-time use. It is used in conjunction with CSP to selectively allow certain inline scripts or styles to execute, bypassing strict CSP directives.
26
+
27
+
### Why use a nonce?
28
+
29
+
Even though CSPs are designed to block malicious scripts, there are legitimate scenarios where inline scripts are necessary. In such cases, nonces offer a way to allow these scripts to execute if they have the correct nonce.
30
+
31
+
### Adding a nonce with Middleware
32
+
33
+
[Middleware](/docs/app/building-your-application/routing/middleware) enables you to add headers and generate nonces before the page renders.
34
+
35
+
Every time a page is viewed, a fresh nonce should be generated. This means that you **must use dynamic rendering to add nonces**.
By default, Middleware runs on all requests. You can filter Middleware to run on specific paths using a [`matcher`](/docs/app/building-your-application/routing/middleware#matcher).
112
+
113
+
We recommend ignoring matching prefetches (from `next/link`) and static assets that don't need the CSP header.
114
+
115
+
```ts filename="middleware.ts" switcher
116
+
exportconst config = {
117
+
matcher: [
118
+
/*
119
+
* Match all request paths except for the ones starting with:
You can now read the nonce from a [Server Component](/docs/app/building-your-application/rendering/server-components) using [`headers`](/docs/app/api-reference/functions/headers):
160
+
161
+
```tsx filename="app/page.tsx" switcher
162
+
import { headers } from'next/headers'
163
+
importScriptfrom'next/script'
164
+
165
+
exportdefaultfunction Page() {
166
+
const nonce =headers().get('x-nonce')
167
+
168
+
return (
169
+
<Script
170
+
src="https://www.googletagmanager.com/gtag/js"
171
+
strategy="afterInteractive"
172
+
nonce={nonce}
173
+
/>
174
+
)
175
+
}
176
+
```
177
+
178
+
```jsx filename="app/page.jsx" switcher
179
+
import { headers } from'next/headers'
180
+
importScriptfrom'next/script'
181
+
182
+
exportdefaultfunctionPage() {
183
+
constnonce=headers().get('x-nonce')
184
+
185
+
return (
186
+
<Script
187
+
src="https://www.googletagmanager.com/gtag/js"
188
+
strategy="afterInteractive"
189
+
nonce={nonce}
190
+
/>
191
+
)
192
+
}
193
+
```
194
+
195
+
## Version History
196
+
197
+
We recommend using `v13.4.20+` of Next.js to properly handle and apply nonces.
Copy file name to clipboardExpand all lines: docs/02-app/02-api-reference/01-components/image.mdx
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -615,7 +615,7 @@ module.exports = {
615
615
616
616
### `dangerouslyAllowSVG`
617
617
618
-
The default [loader](#loader) does not optimize SVG images for a few reasons. First, SVG is a vector format meaning it can be resized losslessly. Second, SVG has many of the same features as HTML/CSS, which can lead to vulnerabilities without proper [Content Security Policy (CSP) headers](/docs/app/api-reference/next-config-js/headers).
618
+
The default [loader](#loader) does not optimize SVG images for a few reasons. First, SVG is a vector format meaning it can be resized losslessly. Second, SVG has many of the same features as HTML/CSS, which can lead to vulnerabilities without a proper [Content Security Policy](/docs/app/building-your-application/configuring/content-security-policy).
619
619
620
620
If you need to serve SVG images with the default Image Optimization API, you can set `dangerouslyAllowSVG` inside your `next.config.js`:
Copy file name to clipboardExpand all lines: docs/02-app/02-api-reference/05-next-config-js/headers.mdx
+44-52Lines changed: 44 additions & 52 deletions
Original file line number
Diff line number
Diff line change
@@ -388,24 +388,50 @@ module.exports = {
388
388
389
389
## Cache-Control
390
390
391
-
You can set the `Cache-Control`header in your [Next.js API Routes](/docs/pages/building-your-application/routing/api-routes) by using the `res.setHeader` method:
391
+
You cannot set `Cache-Control`headers in `next.config.js` for pages or assets, as these headers will be overwritten in production to ensure that responses and static assets are cached effectively.
392
392
393
-
```js filename="pages/api/user.js"
394
-
exportdefaultfunctionhandler(req, res) {
393
+
<AppOnly>
394
+
395
+
Learn more about [caching](/docs/app/building-your-application/caching) with the App Router.
396
+
397
+
</AppOnly>
398
+
399
+
<PagesOnly>
400
+
401
+
If you need to revalidate the cache of a page that has been [statically generated](/docs/pages/building-your-application/rendering/static-site-generation), you can do so by setting the `revalidate` prop in the page's [`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props) function.
402
+
403
+
You can set the `Cache-Control` header in your [API Routes](/docs/pages/building-your-application/routing/api-routes) by using the `res.setHeader` method:
res.status(200).json({ message: 'Hello from Next.js!' })
397
418
}
398
419
```
399
420
400
-
You cannot set `Cache-Control` headers in `next.config.js` file as these will be overwritten in production to ensure that API Routes and static assets are cached effectively.
421
+
```js filename="pages/api/hello.js" switcher
422
+
exportdefaultfunctionhandler(req, res) {
423
+
res.setHeader('Cache-Control', 's-maxage=86400')
424
+
res.status(200).json({ message:'Hello from Next.js!' })
425
+
}
426
+
```
401
427
402
-
If you need to revalidate the cache of a page that has been [statically generated](/docs/pages/building-your-application/rendering/static-site-generation), you can do so by setting the `revalidate` prop in the page's [`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props) function.
428
+
</PagesOnly>
403
429
404
430
## Options
405
431
406
432
### X-DNS-Prefetch-Control
407
433
408
-
This header controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so the [DNS](https://developer.mozilla.org/en-US/docs/Glossary/DNS) is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.
434
+
[This header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control) controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so the [DNS](https://developer.mozilla.org/en-US/docs/Glossary/DNS) is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.
409
435
410
436
```js
411
437
{
@@ -416,19 +442,9 @@ This header controls DNS prefetching, allowing browsers to proactively perform d
416
442
417
443
### Strict-Transport-Security
418
444
419
-
This header informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration below, all present and future subdomains will use HTTPS for a `max-age` of 2 years. This blocks access to pages or subdomains that can only be served over HTTP.
420
-
421
-
<AppOnly>
445
+
[This header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration below, all present and future subdomains will use HTTPS for a `max-age` of 2 years. This blocks access to pages or subdomains that can only be served over HTTP.
422
446
423
-
If you're deploying to [Vercel](https://vercel.com/docs/concepts/edge-network/headers#strict-transport-security?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), this header is not necessary as it's automatically added to all deployments unless you declare [`headers`](/docs/app/api-reference/next-config-js/headers) in your `next.config.js`.
424
-
425
-
</AppOnly>
426
-
427
-
<PagesOnly>
428
-
429
-
If you're deploying to [Vercel](https://vercel.com/docs/concepts/edge-network/headers#strict-transport-security?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), this header is not necessary as it's automatically added to all deployments unless you declare [`headers`](/docs/pages/api-reference/next-config-js/headers) in your `next.config.js`.
430
-
431
-
</PagesOnly>
447
+
If you're deploying to [Vercel](https://vercel.com/docs/concepts/edge-network/headers#strict-transport-security?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), this header is not necessary as it's automatically added to all deployments unless you declare `headers` in your `next.config.js`.
432
448
433
449
```js
434
450
{
@@ -439,7 +455,9 @@ If you're deploying to [Vercel](https://vercel.com/docs/concepts/edge-network/he
439
455
440
456
### X-Frame-Options
441
457
442
-
This header indicates whether the site should be allowed to be displayed within an `iframe`. This can prevent against clickjacking attacks. This header has been superseded by CSP's `frame-ancestors` option, which has better support in modern browsers.
458
+
[This header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) indicates whether the site should be allowed to be displayed within an `iframe`. This can prevent against clickjacking attacks.
459
+
460
+
**This header has been superseded by CSP's `frame-ancestors` option**, which has better support in modern browsers.
443
461
444
462
```js
445
463
{
@@ -450,7 +468,7 @@ This header indicates whether the site should be allowed to be displayed within
450
468
451
469
### Permissions-Policy
452
470
453
-
This header allows you to control which features and APIs can be used in the browser. It was previously named `Feature-Policy`. You can view the full list of permission options [here](https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md).
471
+
[This header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy) allows you to control which features and APIs can be used in the browser. It was previously named `Feature-Policy`.
454
472
455
473
```js
456
474
{
@@ -461,7 +479,9 @@ This header allows you to control which features and APIs can be used in the bro
461
479
462
480
### X-Content-Type-Options
463
481
464
-
This header prevents the browser from attempting to guess the type of content if the `Content-Type` header is not explicitly set. This can prevent XSS exploits for websites that allow users to upload and share files. For example, a user trying to download an image, but having it treated as a different `Content-Type` like an executable, which could be malicious. This header also applies to downloading browser extensions. The only valid value for this header is `nosniff`.
482
+
[This header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) prevents the browser from attempting to guess the type of content if the `Content-Type` header is not explicitly set. This can prevent XSS exploits for websites that allow users to upload and share files.
483
+
484
+
For example, a user trying to download an image, but having it treated as a different `Content-Type` like an executable, which could be malicious. This header also applies to downloading browser extensions. The only valid value for this header is `nosniff`.
465
485
466
486
```js
467
487
{
@@ -472,7 +492,7 @@ This header prevents the browser from attempting to guess the type of content if
472
492
473
493
### Referrer-Policy
474
494
475
-
This header controls how much information the browser includes when navigating from the current website (origin) to another. You can read about the different options [here](https://scotthelme.co.uk/a-new-security-header-referrer-policy/).
495
+
[This header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) controls how much information the browser includes when navigating from the current website (origin) to another.
476
496
477
497
```js
478
498
{
@@ -483,35 +503,7 @@ This header controls how much information the browser includes when navigating f
483
503
484
504
### Content-Security-Policy
485
505
486
-
This header helps prevent cross-site scripting (XSS), clickjacking and other code injection attacks. Content Security Policy (CSP) can specify allowed origins for content including scripts, stylesheets, images, fonts, objects, media (audio, video), iframes, and more.
487
-
488
-
You can read about the many different CSP options [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
489
-
490
-
You can add Content Security Policy directives using a template string.
491
-
492
-
```js
493
-
// Before defining your Security Headers
494
-
// add Content Security Policy directives using a template string.
495
-
496
-
constContentSecurityPolicy=`
497
-
default-src 'self';
498
-
script-src 'self';
499
-
child-src example.com;
500
-
style-src 'self' example.com;
501
-
font-src 'self';
502
-
`
503
-
```
504
-
505
-
When a directive uses a keyword such as `self`, wrap it in single quotes `''`.
506
-
507
-
In the header's value, replace the new line with a space.
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
0 commit comments