export default withSecureHeaders({
contentSecurityPolicy: {
directives: {
defaultSrc: "'self'",
styleSrc: ["'self'", "https://stackpath.bootstrapcdn.com"],
},
},
forceHTTPSRedirect: [true, { maxAge: 60 * 60 * 24 * 4, includeSubDomains: true }],
referrerPolicy: "same-origin",
})(Application);
Table of Contents
Features
FEATURES | WHAT YOU CAN DO |
---|
⚛️ Designed for Next.js | Use for page components in /pages |
✨ Default applied rules | Help your project even if you don't have knowledge |
🎩 Type Safe | You can use with TypeScript |
next-secure-headers is a similar to Helmet which sets HTTP response headers related to
security for Express.js.
Next.js supports to be used in Node.js frameworks such as Express.js. So you can use Helmet with your Next.js project if you
create a custom server, but a custom server is not recommended by Next.js development team. Also they are working to implement
in order to be possible to use Next.js without a custom server. In fact, Next.js 9 supports
Dynamic Routing, so we don't need to build a custom server in order to
implement it using such as next-routes which requires a custom server.
import withSecureHeaders from "next-secure-headers";
class Application extends App {
...
}
export default withSecureHeaders()(Application);
If you want to use Helmet, it requires to use a custom server against a recommended way. To solve this problem, next-secure-headers
was born. next-secure-headers is built for Next.js project, so you can use it in page components as HOC like other libraries for
Next.js such as next-redux-wrapper.
The following are rules next-secure-headers has and Helmet has. next-secure-headers is inspired by Helmet, but it don't have
some rules for some reason.
| next-secure-headers | Helmet | Comment |
---|
Strict-Transport-Security | forceHTTPSRedirect | hsts | |
X-Frame-Options | frameGuard | frameguard | |
X-Download-Options | noopen | ieNoOpen | |
X-Content-Type-Options | nosniff | noSniff | |
X-XSS-Protection | xssProtection | xssFilter | |
Content-Security-Policy | contentSecurityPolicy | contentSecurityPolicy | |
Expect-CT | expectCT | expectCt | |
Referrer-Policy | referrerPolicy | referrerPolicy | |
X-DNS-Prefetch-Control | - | dnsPrefetchControl | This has privacy implications but this improves performance. |
Feature-Policy | - | featurePolicy | Feature Policy improves security but it is working draft yet. |
X-Powered-By | - | hidePoweredBy | Next.js supports to remove this header in next.config.js . |
Related to cache | - | nocache | As Helmet said, caching has lots of benefits. |
X-Permitted-Cross-Domain-Policies | - | crossdomain | Adobe Flash is one of old web technologies. |
Quick Start
Requirements
- npm or Yarn
- Node.js 10.0.0 or higher
- Next.js 8.0.0 or higher
Installation
$ npm install next-secure-headers
If you are using Yarn, use the following command.
$ yarn add next-secure-headers
Setup
Firstly use an exported function for your Next.js application in /pages/_app.tsx
. Also you can use in any
page components in /pages/xxx.tsx
instead.
import withSecureHeaders from "next-secure-headers";
class Application extends App {
...
}
export default withSecureHeaders()(Application);
By default, next-secure-headers applies some rules. If you want to enable or disable rules, you can give settings to the first
argument of the function.
export default withSecureHeaders({
contentSecurityPolicy: {
directives: {
defaultSrc: "'self'",
styleSrc: ["'self'", "https://stackpath.bootstrapcdn.com"],
},
},
forceHTTPSRedirect: [true, { maxAge: 60 * 60 * 24 * 4, includeSubDomains: true }],
referrerPolicy: "same-origin",
})(Application);
Rules
forceHTTPSRedirect
{
forceHTTPSRedirect: boolean | [true, Partial<{ maxAge: number; includeSubDomains: boolean; preload: boolean }>];
}
This is to set "Strict-Transport-Security (HSTS)" header and it's to prevent man-in-the-middle attacks during redirects from
HTTP to HTTPS. To enable this is highly recommended if you use HTTPS (SSL) on your servers.
You can give true
if you want to enable this rule, or you can specify options by giving [true, OPTION_OBJECT]
. By default,
this sets max-age
to two years (63,072,000 seconds).
frameGuard
{
frameGuard: false | "deny" | "sameorigin" | ["allow-from", { uri: string | URL }];
}
This is to set "X-Frame-Options" header and it's to prevent clickjacking attacks. "deny"
is highly recommended if you don't
use frame elements such as iframe
.
noopen
{
noopen: false | "noopen";
}
This is to set "X-Download-Options" header and it's to prevent to open downloaded files automatically for IE8+ (MIME Handling
attacks).
nosniff
{
nosniff: false | "nosniff";
}
This is to set "X-Content-Type-Options" header and it's to prevent MIME Sniffing attacks.
xssProtection
{
xssProtection: false | "sanitize" | "block-rendering" | ["report", { uri: string | URL }];
}
This is to set "X-XSS-Protection" header and it's to prevent XSS attacks.
If you specify "sanitize"
, this sets the header to "1"
and browsers will sanitize unsafe area. If you specify
"block-rendering"
, this sets the header to "1; mode=block"
and browsers will block rendering a page. "X-XSS-Protection"
blocks many XSS attacks, but Content Security Policy is recommended to use compared to this.
contentSecurityPolicy
{
contentSecurityPolicy:
| false
| {
directives:
& Partial<{
childSrc: string | string[];
connectSrc: string | string[];
defaultSrc: string | string[];
fontSrc: string | string[];
frameSrc: string | string[];
imgSrc: string | string[];
manifestSrc: string | string[];
mediaSrc: string | string[];
prefetchSrc: string | string[];
objectSrc: string | string[];
scriptSrc: string | string[];
scriptSrcElem: string | string[];
scriptSrcAttr: string | string[];
styleSrc: string | string[];
styleSrcElem: string | string[];
styleSrcAttr: string | string[];
workerSrc: string | string[];
}>
& Partial<{
baseURI: string | string[];
pluginTypes: string | string[];
sandbox:
| true
| "allow-downloads-without-user-activation"
| "allow-forms"
| "allow-modals"
| "allow-orientation-lock"
| "allow-pointer-lock"
| "allow-popups"
| "allow-popups-to-escape-sandbox"
| "allow-presentation"
| "allow-same-origin"
| "allow-scripts"
| "allow-storage-access-by-user-activation"
| "allow-top-navigation"
| "allow-top-navigation-by-user-activation";
}>
& Partial<{
navigateTo: string | string[];
reportURI: string | URL | (string | URL)[];
reportTo: object;
}>;
reportOnly?: boolean;
};
}
This is to set "Content-Security-Policy" or "Content-Security-Policy-Report-Only" header and it's to prevent to load and execute
non-allowed resources.
If you give true to reportOnly
, this sets "Content-Security-Policy-Report-Only" to value instead of "Content-Security-Policy".
expectCT
{
expectCT: boolean | [true, Partial<{ maxAge: number; enforce: boolean; reportURI: string | URL }>];
}
This is to set "Expect-CT" header and it's to tell browsers to expect Certificate Transparency.
referrerPolicy
{
referrerPolicy:
| false
| "no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin"
| ("no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin")[];
}
This is to set "Referrer-Policy" header and it's to prevent to be got referrer by other servers. You can specify one or more
values for legacy browsers which does not support a specific value.
API
Default Export
import withSecureHeaders from "next-secure-headers";
export default withSecureHeaders({ referrerPolicy: "same-origin" })(Page);
next-secure-headers exports a HOC for Next.js as default export. You can use this function for application ( /pages/_app.tsx
)
and page components ( /pages/xxx.tsx
).
withSecureHeaders(OPTIONS)(APPLICATION_OR_COMPONENT);
The first argument accepts options for rules, and the argument of the returned function accepts application or page components.
The returned value is a new React component.
import { createHeadersObject } from "next-secure-headers";
createHeadersObject({ referrerPolicy: "same-origin" });
createHeadersObject
is a function to return HTTP headers as object.
createHeadersObject(OPTIONS);
The first argument accepts options for rules.
Recipes
In general, X-Powered-By HTTP response header should be removed from response headers because it helps hackers to get the server
information.
next-secure-headers does not support to remove X-Powered-By header, but Next.js supports to do.
module.exports = {
poweredByHeader: false,
};
If you give false to poweredByHeader
in next.config.js
, Next.js removes the header from response headers.
export default withSecureHeaders({ referrerPolicy: "same-origin" })(Application);
export default withSecureHeaders({ referrerPolicy: "no-referrer-when-downgrade" })(Page);
next-secure-headers does not support to override response headers in child page components because of being restricted by Next.js
architecture.
import withSecureHeaders from "next-secure-headers";
export const secureHeadersDefaultOption: Parameters<typeof withSecureHeaders>[0] = {
referrerPolicy: "same-origin",
};
import { secureHeadersDefaultOption } from "../config/secure-headers";
export default withSecureHeaders(secureHeadersDefaultOption)(Application);
export default withSecureHeaders({
...secureHeadersDefaultOption,
referrerPolicy: "no-referrer-when-downgrade",
})(Page);
To solve this, you should define the option as one module, then you should import and merge the object.
Bug reports and pull requests are welcome on GitHub at
https://github.com/jagaapple/next-secure-headers. This project
is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the
Contributor Covenant code of conduct.
Please read Contributing Guidelines before development and contributing.
License
The library is available as open source under the terms of the MIT License.
Copyright 2019 Jaga Apple. All rights reserve