next-safe helps secure your Next.js apps by providing sensible defaults for the most common security headers, including:
Content-Security-PolicyPermissions-Policy(formerly known asFeature-Policy)Referrer-PolicyX-Content-Type-OptionsX-Frame-OptionsX-XSS-Protection
npmor Yarn- Node.js
- Next.js 9.5+
npm install next-safe
# OR
yarn add next-safenext-safe exports a single function that generates all of your headers. In your next.config.js file, you can pass these directly into the headers key for any route you want to set the headers on.
const nextSafe = require('next-safe')
const isDev = process.env.NODE_ENV === 'production'
module.exports = {
async headers () {
return [
{
source: '/:path*',
headers: nextSafe({ isDev }),
},
]
},
}By default, this sets all of the headers you need and provides substantial protections for your Next.js application. However, the defaults are also super strict. See the Configuration section for details on how to make next-safe a bit more flexible.
next-safe allows you to configure every header that it generates.
nextSafe({
contentTypeOptions,
contentSecurityPolicy: {
reportOnly,
},
frameOptions,
permissionsPolicy,
permissionsPolicyDirectiveSupport,
isDev,
referrerPolicy,
xssProtection,
})nosniff
contentTypeOptions controls the value of the X-Content-Type-Options header, which tells the browser not to change the MIME types for any downloaded content.
{
contentSecurityPolicy: {
"base-uri": "'none'",
"child-src": "'none'",
"connect-src": "'self'",
"default-src": "'self'",
"font-src": "'self'",
"form-action": "'self'",
"frame-ancestors": "'none'",
"frame-src": "'none'",
"img-src": "'self'",
"manifest-src": "'self'",
"object-src": "'none'",
"prefetch-src": "'self'",
"script-src": "'self'",
"style-src": "'self'",
"worker-src": "'self'",
},
}Additionally, if isDev is set to true:
{
contentSecurityPolicy: {
"connect-src": "webpack://*",
"script-src": "'unsafe-eval'",
},
}contentSecurityPolicy controls the Content-Security-Policy header. It takes an object, in which each key is a CSP directive and the value of that key is an array of sources. For example:
{
contentSecurityPolicy: {
"img-src": ["'self'", "unsplash.com"],
},
}Note that 'self' is in quotes. This is a CSP thing and next-safe does not handle it for you. The special sources (such as 'self', 'none', etc) must be wrapped in single quotes.
{
contentSecurityPolicy: {
"default-src": ["'self'"],
},
}{
contentSecurityPolicy: {
"base-uri": ["example.com", "foo.example.com", "bar.example.com"],
},
}{
contentSecurityPolicy: {
"upgrade-insecure-requests": [],
},
}{
contentSecurityPolicy: {
"prefetch-src": false,
},
}Setting contentSecurityPolicy.reportOnly to true will rename the Content-Security-Policy header to Content-Security-Policy-Report-Only. This is useful if you want to test your CSP without breaking your site. Make sure to also set up an endpoint to receive the reports, then set up your contentSecurityPolicy.report-to field to point to the endpoint.
DENY
frameOptions controls the value of the X-Frame-Options header.
permissionsPolicy controls the value of the Permissions-Policy header, as well as the legacy Feature-Policy header. This header is used to enable/disable certain features for a website.
By default, all features are set to 'none' unless you tell next-safe otherwise.
{
permissionsPolicyDirectiveSupport: ["proposed", "standard"],
}The Permissions-Policy header has had a bit of a rocky history, and as such the list of features/permissions has changed a lot. To help manage this, next-safe provides 4 different sets of directive support.
To include a list of directives, just add it to the permissionsPolicyDirectiveSupport array. For example, to add support for experimental directives:
{
permissionsPolicyDirectiveSupport: ["proposed", "standard", "experimental"],
}The below table lists all of the features included in each of the 4 directive sets.
| Directive Set | Included Directives |
|---|---|
standard |
accelerometerambient-light-sensorautoplaybatterycameracross-origin-isolateddisplay-capturedocument-domainencrypted-mediaexecution-while-not-renderedexecution-while-out-of-viewportfullscreengeolocationgyroscopemagnetometermicrophonemidinavigation-overridepaymentpicture-in-picturepublickey-credentials-getscreen-wake-locksync-xhrusbweb-sharexr-spatial-tracking |
proposed |
clipboard-readclipboard-writegamepadspeaker-selection |
experimental |
conversion-measurementfocus-without-user-activationhididle-detectionserialsync-scripttrust-token-redemptionvertical-scroll |
legacy |
animationsdocument-writeimage-compressionlayout-animationslegacy-image-formatsmax-downscaling-imagenotificationsoversized-imagespushspeakerunsized-mediavibratevrwake-lockwebauthnweb-share |
false
This tells next-safe if it should be operating in development mode. Specifically, it adds some values to the CSP header to allow the site to continue operating when running next dev.
no-referrer
referrerPolicy controls the Referrer-Policy header, which tells the browser whether or not to send the Referrer header when the site makes a request, or the user clicks on a link.
1; mode=block
xssProtection controls the value of the X-XSS-Protection header. This header is mostly for backwards compatibility. It enables some security features in older browsers that dobn't support CSP.
In some cases, next-safe sends the same header under different header names to support backwards compatibility. For example, Content-Security-Policy is the header that all modern browsers support, but when CSP was still in its infancy various browsers decided to use the X-Content-Security-Policy or X-WebKit-CSP headers. next-safe uses the same content for these headers, but still sends them to support older browsers.
Not all browsers are as up-to-date as next-safe with the standardized features of the Permissions-Policy header. As such, some features will cause warnings to show up in the console. These can also occur if you're using the experimental or legacy feature lists. These warnings are harmless and can safely be ignored.