- Notifications
You must be signed in to change notification settings - Fork375
Help secure Express apps with various HTTP headers
License
helmetjs/helmet
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Help secure Express apps by setting HTTP response headers.
importhelmetfrom"helmet";constapp=express();app.use(helmet());
Helmet sets the following headers by default:
Content-Security-Policy
: A powerful allow-list of what can happen on your page which mitigates many attacksCross-Origin-Opener-Policy
: Helps process-isolate your pageCross-Origin-Resource-Policy
: Blocks others from loading your resources cross-originOrigin-Agent-Cluster
: Changes process isolation to be origin-basedReferrer-Policy
: Controls theReferer
headerStrict-Transport-Security
: Tells browsers to prefer HTTPSX-Content-Type-Options
: AvoidsMIME sniffingX-DNS-Prefetch-Control
: Controls DNS prefetchingX-Download-Options
: Forces downloads to be saved (Internet Explorer only)X-Frame-Options
: Legacy header that mitigatesclickjacking attacksX-Permitted-Cross-Domain-Policies
: Controls cross-domain behavior for Adobe products, like AcrobatX-Powered-By
: Info about the web server. Removed because it could be used in simple attacksX-XSS-Protection
: Legacy header that tries to mitigateXSS attacks, but makes things worse, so Helmet disables it
Each header can be configured. For example, here's how you configure theContent-Security-Policy
header:
// Configure the Content-Security-Policy header.app.use(helmet({contentSecurityPolicy:{directives:{"script-src":["'self'","example.com"],},},}),);
Headers can also be disabled. For example, here's how you disable theContent-Security-Policy
andX-Download-Options
headers:
// Disable the Content-Security-Policy and X-Download-Options headersapp.use(helmet({contentSecurityPolicy:false,xDownloadOptions:false,}),);
Content-Security-Policy
Default:
Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
TheContent-Security-Policy
header mitigates a large number of attacks, such ascross-site scripting. SeeMDN's introductory article on Content Security Policy.
This header is powerful but likely requires some configuration for your specific app.
To configure this header, pass an object with a nesteddirectives
object. Each key is a directive name in camel case (such asdefaultSrc
) or kebab case (such asdefault-src
). Each value is an array (or other iterable) of strings or functions for that directive. If a function appears in the array, it will be called with the request and response objects.
// Sets all of the defaults, but overrides `script-src`// and disables the default `style-src`.app.use(helmet({contentSecurityPolicy:{directives:{"script-src":["'self'","example.com"],"style-src":null,},},}),);
// Sets the `script-src` directive to// "'self' 'nonce-e33cc...'"// (or similar)app.use((req,res,next)=>{res.locals.cspNonce=crypto.randomBytes(32).toString("hex");next();});app.use(helmet({contentSecurityPolicy:{directives:{scriptSrc:["'self'",(req,res)=>`'nonce-${res.locals.cspNonce}'`],},},}),);
These directives are merged into a default policy, which you can disable by settinguseDefaults
tofalse
.
// Sets "Content-Security-Policy: default-src 'self';// script-src 'self' example.com;object-src 'none';// upgrade-insecure-requests"app.use(helmet({contentSecurityPolicy:{useDefaults:false,directives:{defaultSrc:["'self'"],scriptSrc:["'self'","example.com"],objectSrc:["'none'"],upgradeInsecureRequests:[],},},}),);
You can get the default directives object withhelmet.contentSecurityPolicy.getDefaultDirectives()
. Here is the default policy (formatted for readability):
default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
Thedefault-src
directive can be explicitly disabled by setting its value tohelmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc
, but this is not recommended.
You can set theContent-Security-Policy-Report-Only
instead:
// Sets the Content-Security-Policy-Report-Only headerapp.use(helmet({contentSecurityPolicy:{directives:{/* ... */},reportOnly:true,},}),);
Helmet performs very little validation on your CSP. You should rely on CSP checkers likeCSP Evaluator instead.
To disable theContent-Security-Policy
header:
app.use(helmet({contentSecurityPolicy:false,}),);
You can use this as standalone middleware withapp.use(helmet.contentSecurityPolicy())
.
Cross-Origin-Embedder-Policy
This header is not set by default.
TheCross-Origin-Embedder-Policy
header helps control what resources can be loaded cross-origin. SeeMDN's article on this header for more.
// Helmet does not set Cross-Origin-Embedder-Policy// by default.app.use(helmet());// Sets "Cross-Origin-Embedder-Policy: require-corp"app.use(helmet({crossOriginEmbedderPolicy:true}));// Sets "Cross-Origin-Embedder-Policy: credentialless"app.use(helmet({crossOriginEmbedderPolicy:{policy:"credentialless"}}));
You can use this as standalone middleware withapp.use(helmet.crossOriginEmbedderPolicy())
.
Cross-Origin-Opener-Policy
Default:
Cross-Origin-Opener-Policy: same-origin
TheCross-Origin-Opener-Policy
header helps process-isolate your page. For more, seeMDN's article on this header.
// Sets "Cross-Origin-Opener-Policy: same-origin"app.use(helmet());// Sets "Cross-Origin-Opener-Policy: same-origin-allow-popups"app.use(helmet({crossOriginOpenerPolicy:{policy:"same-origin-allow-popups"},}),);
To disable theCross-Origin-Opener-Policy
header:
app.use(helmet({crossOriginOpenerPolicy:false,}),);
You can use this as standalone middleware withapp.use(helmet.crossOriginOpenerPolicy())
.
Cross-Origin-Resource-Policy
Default:
Cross-Origin-Resource-Policy: same-origin
TheCross-Origin-Resource-Policy
header blocks others from loading your resources cross-origin in some cases. For more, see"Consider deploying Cross-Origin Resource Policy" andMDN's article on this header.
// Sets "Cross-Origin-Resource-Policy: same-origin"app.use(helmet());// Sets "Cross-Origin-Resource-Policy: same-site"app.use(helmet({crossOriginResourcePolicy:{policy:"same-site"}}));
To disable theCross-Origin-Resource-Policy
header:
app.use(helmet({crossOriginResourcePolicy:false,}),);
You can use this as standalone middleware withapp.use(helmet.crossOriginResourcePolicy())
.
Origin-Agent-Cluster
Default:
Origin-Agent-Cluster: ?1
TheOrigin-Agent-Cluster
header provides a mechanism to allow web applications to isolate their origins from other processes. Read more about itin the spec.
This header takes no options and is set by default.
// Sets "Origin-Agent-Cluster: ?1"app.use(helmet());
To disable theOrigin-Agent-Cluster
header:
app.use(helmet({originAgentCluster:false,}),);
You can use this as standalone middleware withapp.use(helmet.originAgentCluster())
.
Referrer-Policy
Default:
Referrer-Policy: no-referrer
TheReferrer-Policy
header which controls what information is set intheReferer
request header. See"Referer header: privacy and security concerns" andthe header's documentation on MDN for more.
// Sets "Referrer-Policy: no-referrer"app.use(helmet());
policy
is a string or array of strings representing the policy. If passed as an array, it will be joined with commas, which is useful when settinga fallback policy. It defaults tono-referrer
.
// Sets "Referrer-Policy: no-referrer"app.use(helmet({referrerPolicy:{policy:"no-referrer",},}),);// Sets "Referrer-Policy: origin,unsafe-url"app.use(helmet({referrerPolicy:{policy:["origin","unsafe-url"],},}),);
To disable theReferrer-Policy
header:
app.use(helmet({referrerPolicy:false,}),);
You can use this as standalone middleware withapp.use(helmet.referrerPolicy())
.
Strict-Transport-Security
Default:
Strict-Transport-Security: max-age=31536000; includeSubDomains
TheStrict-Transport-Security
header tells browsers to prefer HTTPS instead of insecure HTTP. Seethe documentation on MDN for more.
// Sets "Strict-Transport-Security: max-age=31536000; includeSubDomains"app.use(helmet());
maxAge
is the number of seconds browsers should remember to prefer HTTPS. If passed a non-integer, the value is rounded down. It defaults to 365 days.
includeSubDomains
is a boolean which dictates whether to include theincludeSubDomains
directive, which makes this policy extend to subdomains. It defaults totrue
.
preload
is a boolean. If true, it adds thepreload
directive, expressing intent to add your HSTS policy to browsers. Seethe "Preloading Strict Transport Security" section on MDN for more. It defaults tofalse
.
// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains"app.use(helmet({strictTransportSecurity:{maxAge:123456,},}),);// Sets "Strict-Transport-Security: max-age=123456"app.use(helmet({strictTransportSecurity:{maxAge:123456,includeSubDomains:false,},}),);// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains; preload"app.use(helmet({strictTransportSecurity:{maxAge:63072000,preload:true,},}),);
To disable theStrict-Transport-Security
header:
app.use(helmet({strictTransportSecurity:false,}),);
You may wish to disable this header for local development, as it can make your browser force redirects fromhttp://localhost
tohttps://localhost
, which may not be desirable if you develop multiple apps usinglocalhost
. Seethis issue for more discussion.
You can use this as standalone middleware withapp.use(helmet.strictTransportSecurity())
.
X-Content-Type-Options
Default:
X-Content-Type-Options: nosniff
TheX-Content-Type-Options
mitigatesMIME type sniffing which can cause security issues. Seedocumentation for this header on MDN for more.
This header takes no options and is set by default.
// Sets "X-Content-Type-Options: nosniff"app.use(helmet());
To disable theX-Content-Type-Options
header:
app.use(helmet({xContentTypeOptions:false,}),);
You can use this as standalone middleware withapp.use(helmet.xContentTypeOptions())
.
X-DNS-Prefetch-Control
Default:
X-DNS-Prefetch-Control: off
TheX-DNS-Prefetch-Control
header helps control DNS prefetching, which can improve user privacy at the expense of performance. Seedocumentation on MDN for more.
// Sets "X-DNS-Prefetch-Control: off"app.use(helmet());
allow
is a boolean dictating whether to enable DNS prefetching. It defaults tofalse
.
Examples:
// Sets "X-DNS-Prefetch-Control: off"app.use(helmet({xDnsPrefetchControl:{allow:false},}),);// Sets "X-DNS-Prefetch-Control: on"app.use(helmet({xDnsPrefetchControl:{allow:true},}),);
To disable theX-DNS-Prefetch-Control
header and use the browser's default value:
app.use(helmet({xDnsPrefetchControl:false,}),);
You can use this as standalone middleware withapp.use(helmet.xDnsPrefetchControl())
.
X-Download-Options
Default:
X-Download-Options: noopen
TheX-Download-Options
header is specific to Internet Explorer 8. It forces potentially-unsafe downloads to be saved, mitigating execution of HTML in your site's context. For more, seethis old post on MSDN.
This header takes no options and is set by default.
// Sets "X-Download-Options: noopen"app.use(helmet());
To disable theX-Download-Options
header:
app.use(helmet({xDownloadOptions:false,}),);
You can use this as standalone middleware withapp.use(helmet.xDownloadOptions())
.
X-Frame-Options
Default:
X-Frame-Options: SAMEORIGIN
The legacyX-Frame-Options
header to help you mitigateclickjacking attacks. This header is superseded bytheframe-ancestors
Content Security Policy directive but is still useful on old browsers or if no CSP is used. For more, seethe documentation on MDN.
// Sets "X-Frame-Options: SAMEORIGIN"app.use(helmet());
action
is a string that specifies which directive to use—eitherDENY
orSAMEORIGIN
. (A legacy directive,ALLOW-FROM
, is not supported by Helmet.Read more here.) It defaults toSAMEORIGIN
.
Examples:
// Sets "X-Frame-Options: DENY"app.use(helmet({xFrameOptions:{action:"deny"},}),);// Sets "X-Frame-Options: SAMEORIGIN"app.use(helmet({xFrameOptions:{action:"sameorigin"},}),);
To disable theX-Frame-Options
header:
app.use(helmet({xFrameOptions:false,}),);
You can use this as standalone middleware withapp.use(helmet.xFrameOptions())
.
X-Permitted-Cross-Domain-Policies
Default:
X-Permitted-Cross-Domain-Policies: none
TheX-Permitted-Cross-Domain-Policies
header tells some clients (mostly Adobe products) your domain's policy for loading cross-domain content. Seethe description on OWASP for more.
// Sets "X-Permitted-Cross-Domain-Policies: none"app.use(helmet());
permittedPolicies
is a string that must be"none"
,"master-only"
,"by-content-type"
, or"all"
. It defaults to"none"
.
Examples:
// Sets "X-Permitted-Cross-Domain-Policies: none"app.use(helmet({xPermittedCrossDomainPolicies:{permittedPolicies:"none",},}),);// Sets "X-Permitted-Cross-Domain-Policies: by-content-type"app.use(helmet({xPermittedCrossDomainPolicies:{permittedPolicies:"by-content-type",},}),);
To disable theX-Permitted-Cross-Domain-Policies
header:
app.use(helmet({xPermittedCrossDomainPolicies:false,}),);
You can use this as standalone middleware withapp.use(helmet.xPermittedCrossDomainPolicies())
.
X-Powered-By
Default: theX-Powered-By
header, if present, is removed.
Helmet removes theX-Powered-By
header, which is set by default in Express and some other frameworks. Removing the header offers very limited security benefits (seethis discussion) and is mostly removed to save bandwidth, but may thwart simplistic attackers.
Note:Express has a built-in way to disable theX-Powered-By
header, which you may wish to use instead.
The removal of this header takes no options. The header is removed by default.
To disable this behavior:
// Not required, but recommended for Express users:app.disable("x-powered-by");// Ask Helmet to ignore the X-Powered-By header.app.use(helmet({xPoweredBy:false,}),);
You can use this as standalone middleware withapp.use(helmet.xPoweredBy())
.
X-XSS-Protection
Default:
X-XSS-Protection: 0
Helmet disables browsers' buggy cross-site scripting filter by setting the legacyX-XSS-Protection
header to0
. Seediscussion about disabling the header here anddocumentation on MDN.
This header takes no options and is set by default.
To disable theX-XSS-Protection
header:
// This is not recommended.app.use(helmet({xXssProtection:false,}),);
You can use this as standalone middleware withapp.use(helmet.xXssProtection())
.
About
Help secure Express apps with various HTTP headers