- Notifications
You must be signed in to change notification settings - Fork391
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
Security headers for Express.js apps.
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 theRefererheaderStrict-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 to 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-requestsTheContent-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-requestsThedefault-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,},}),);
upgrade-insecure-requests, a directive that causes browsers to upgrade HTTP to HTTPS, is set by default. You may wish to avoid this in development, as you may not be developing with HTTPS. Notably, Safari will upgradehttp://localhost tohttps://localhost, which can cause problems. To work around this, you may wish to disable theupgrade-insecure-requests directive in development. For example:
constisDevelopment=app.get("env")==="development";app.use(helmet({contentSecurityPolicy:{directives:{// Disable upgrade-insecure-requests in development."upgrade-insecure-requests":isDevelopment ?null :[],},},}),);
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-originTheCross-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-originTheCross-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: ?1TheOrigin-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-referrerTheReferrer-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; includeSubDomainsTheStrict-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: nosniffTheX-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: offTheX-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: noopenTheX-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: SAMEORIGINThe 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: noneTheX-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: 0Helmet 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
Topics
Resources
License
Code of conduct
Contributing
Security policy
Uh oh!
There was an error while loading.Please reload this page.