Helmet is Express middleware that sets 14 security-related HTTP headers protecting against common web vulnerabilities. Install: npm install helmet. Enable: const helmet = require('helmet'); app.use(helmet()). This applies all 14 default header configurations. Helmet is a wrapper combining smaller middlewares - each can be configured individually. Use before route definitions to ensure headers apply to all responses. Express 4.x compatible. Modern alternative: Set headers manually with app.use((req, res, next) => {res.set('X-Frame-Options', 'DENY'); next();}). Helmet provides sensible defaults for production security. NOT a complete security solution - combine with rate limiting, input validation, authentication.
Node.js Helmet Security FAQ & Answers
12 expert Node.js Helmet Security answers researched from official documentation. Every answer cites authoritative sources you can verify.
unknown
12 questionsContent-Security-Policy (CSP) prevents XSS attacks by controlling which resources (scripts, styles, images) can load. Default CSP blocks inline scripts and eval(). Configure: app.use(helmet.contentSecurityPolicy({directives: {defaultSrc: ["'self'"], scriptSrc: ["'self'", 'trusted-cdn.com'], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ['*']}}))). Directives: defaultSrc (fallback for unspecified), scriptSrc (JavaScript sources), styleSrc (CSS), imgSrc (images), connectSrc (AJAX/fetch). Use 'self' for same-origin, 'unsafe-inline' allows inline styles/scripts (avoid if possible), 'unsafe-eval' allows eval (never use). Test CSP in report-only mode first: reportOnly: true. Strict CSP can break functionality - configure carefully for your app.
Strict-Transport-Security (HSTS) forces browsers to only use HTTPS connections, preventing protocol downgrade attacks. Configure with Helmet: app.use(helmet.hsts({maxAge: 31536000, includeSubDomains: true, preload: true})). Parameters: maxAge (seconds to remember HTTPS-only, use 1 year = 31536000), includeSubDomains (applies to all subdomains), preload (submit to browser HSTS preload list). Effect: After first HTTPS visit, browser automatically upgrades HTTP requests to HTTPS for maxAge duration. WARNING: Only enable if your entire site supports HTTPS - no HTTP fallback possible. Test with shorter maxAge first (60 seconds), then increase to 1 year. Protects against man-in-the-middle attacks.
X-Frame-Options prevents clickjacking attacks by controlling whether your site can be embedded in iframes. Configure with Helmet: app.use(helmet.frameguard({action: 'deny'})). Options: 'deny' (never allow iframes), 'sameorigin' (allow same-origin iframes only), 'allow-from' (deprecated, don't use). Clickjacking attack: Attacker embeds your site in transparent iframe, tricks users into clicking invisible buttons. Example: User thinks they're clicking 'Play Video' but actually clicking 'Transfer Money'. X-Frame-Options: DENY prevents all iframe embedding. Use 'sameorigin' if you need to embed your own pages. Modern alternative: Use CSP frame-ancestors directive: frame-ancestors 'self'. Both headers work together for defense in depth.
X-Content-Type-Options: nosniff prevents MIME type sniffing attacks where browsers guess content type instead of trusting Content-Type header. Enable with Helmet: app.use(helmet.noSniff()). Attack scenario: Attacker uploads image.jpg containing JavaScript, server returns Content-Type: image/jpeg, old browsers 'sniff' content and execute as JavaScript. nosniff forces browsers to strictly follow declared Content-Type. Effect: Browser will NOT execute script if Content-Type isn't text/javascript, won't render HTML if Content-Type isn't text/html. Prevents: File upload XSS attacks, polyglot file exploits, content type confusion. Always combine with proper Content-Type headers. Modern browsers default to nosniff behavior, but set explicitly for older browser support.
YES, always remove X-Powered-By header in production. Default Express sends 'X-Powered-By: Express' revealing server technology to attackers. Remove with Helmet: app.use(helmet.hidePoweredBy()). Or manually: app.disable('x-powered-by'). Security by obscurity: Attackers scan for specific frameworks to exploit known vulnerabilities. Example: If attacker sees 'X-Powered-By: Express 4.16.0', they research CVEs for that exact version. Removing header doesn't prevent attacks but raises the bar - forces attacker to fingerprint server via other methods. Also consider: Custom error pages (don't expose stack traces), remove version numbers from all headers, disable directory listing. Defense in depth approach.
Helmet is Express middleware that sets 14 security-related HTTP headers protecting against common web vulnerabilities. Install: npm install helmet. Enable: const helmet = require('helmet'); app.use(helmet()). This applies all 14 default header configurations. Helmet is a wrapper combining smaller middlewares - each can be configured individually. Use before route definitions to ensure headers apply to all responses. Express 4.x compatible. Modern alternative: Set headers manually with app.use((req, res, next) => {res.set('X-Frame-Options', 'DENY'); next();}). Helmet provides sensible defaults for production security. NOT a complete security solution - combine with rate limiting, input validation, authentication.
Content-Security-Policy (CSP) prevents XSS attacks by controlling which resources (scripts, styles, images) can load. Default CSP blocks inline scripts and eval(). Configure: app.use(helmet.contentSecurityPolicy({directives: {defaultSrc: ["'self'"], scriptSrc: ["'self'", 'trusted-cdn.com'], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ['*']}}))). Directives: defaultSrc (fallback for unspecified), scriptSrc (JavaScript sources), styleSrc (CSS), imgSrc (images), connectSrc (AJAX/fetch). Use 'self' for same-origin, 'unsafe-inline' allows inline styles/scripts (avoid if possible), 'unsafe-eval' allows eval (never use). Test CSP in report-only mode first: reportOnly: true. Strict CSP can break functionality - configure carefully for your app.
Strict-Transport-Security (HSTS) forces browsers to only use HTTPS connections, preventing protocol downgrade attacks. Configure with Helmet: app.use(helmet.hsts({maxAge: 31536000, includeSubDomains: true, preload: true})). Parameters: maxAge (seconds to remember HTTPS-only, use 1 year = 31536000), includeSubDomains (applies to all subdomains), preload (submit to browser HSTS preload list). Effect: After first HTTPS visit, browser automatically upgrades HTTP requests to HTTPS for maxAge duration. WARNING: Only enable if your entire site supports HTTPS - no HTTP fallback possible. Test with shorter maxAge first (60 seconds), then increase to 1 year. Protects against man-in-the-middle attacks.
X-Frame-Options prevents clickjacking attacks by controlling whether your site can be embedded in iframes. Configure with Helmet: app.use(helmet.frameguard({action: 'deny'})). Options: 'deny' (never allow iframes), 'sameorigin' (allow same-origin iframes only), 'allow-from' (deprecated, don't use). Clickjacking attack: Attacker embeds your site in transparent iframe, tricks users into clicking invisible buttons. Example: User thinks they're clicking 'Play Video' but actually clicking 'Transfer Money'. X-Frame-Options: DENY prevents all iframe embedding. Use 'sameorigin' if you need to embed your own pages. Modern alternative: Use CSP frame-ancestors directive: frame-ancestors 'self'. Both headers work together for defense in depth.
X-Content-Type-Options: nosniff prevents MIME type sniffing attacks where browsers guess content type instead of trusting Content-Type header. Enable with Helmet: app.use(helmet.noSniff()). Attack scenario: Attacker uploads image.jpg containing JavaScript, server returns Content-Type: image/jpeg, old browsers 'sniff' content and execute as JavaScript. nosniff forces browsers to strictly follow declared Content-Type. Effect: Browser will NOT execute script if Content-Type isn't text/javascript, won't render HTML if Content-Type isn't text/html. Prevents: File upload XSS attacks, polyglot file exploits, content type confusion. Always combine with proper Content-Type headers. Modern browsers default to nosniff behavior, but set explicitly for older browser support.
YES, always remove X-Powered-By header in production. Default Express sends 'X-Powered-By: Express' revealing server technology to attackers. Remove with Helmet: app.use(helmet.hidePoweredBy()). Or manually: app.disable('x-powered-by'). Security by obscurity: Attackers scan for specific frameworks to exploit known vulnerabilities. Example: If attacker sees 'X-Powered-By: Express 4.16.0', they research CVEs for that exact version. Removing header doesn't prevent attacks but raises the bar - forces attacker to fingerprint server via other methods. Also consider: Custom error pages (don't expose stack traces), remove version numbers from all headers, disable directory listing. Defense in depth approach.