What are Security Headers?
Security headers are HTTP response headers that provide an additional layer of security by telling browsers how to behave when handling your website's content. They help mitigate attacks and security vulnerabilities by controlling browser security features.
Properly configured security headers can prevent cross-site scripting (XSS), clickjacking, code injection, and other common web vulnerabilities. They are a simple yet effective way to enhance your web application's security posture.
Essential Security Headers
Advanced Security Headers
Security Headers Best Practices
Implement Content Security Policy (CSP)
Start with a restrictive CSP and use report-only mode initially. Gradually tighten policies while monitoring for breakage. Use nonces or hashes for inline scripts instead of 'unsafe-inline'.
Enable HSTS with Preload
Set HSTS with a long max-age and include subdomains. Consider submitting your site to the HSTS preload list for built-in browser protection.
Use Secure Cookie Attributes
Set HttpOnly, Secure, and SameSite attributes on cookies. Use __Host- and __Secure- prefixes for additional cookie security.
Configure Referrer Policy
Use a restrictive referrer policy like 'strict-origin-when-cross-origin' or 'same-origin' to prevent leaking sensitive URL information.
Regular Security Audits
Use tools like securityheaders.com to audit your headers configuration. Monitor for new header standards and update your implementation accordingly.
Implementation Examples
Nginx Configuration
server {
listen 443 ssl http2;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self';" always;
# Remove server information
server_tokens off;
}
Express.js Middleware
const helmet = require('helmet');
// Basic security headers
app.use(helmet());
// Custom CSP configuration
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.example.com"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
fontSrc: ["'self'"],
connectSrc: ["'self'"],
objectSrc: ["'none'"],
baseUri: ["'self'"],
formAction: ["'self'"]
}
}));
// Additional headers
app.use(helmet.referrerPolicy({ policy: 'strict-origin-when-cross-origin' }));
app.use(helmet.permittedCrossDomainPolicies());
app.use(helmet.expectCt({
maxAge: 86400,
enforce: true
}));
Common Header Misconfigurations
Overly Permissive CSP
Using 'unsafe-inline' or 'unsafe-eval' in CSP defeats the purpose of the header.
Missing HSTS
Not implementing HSTS leaves sites vulnerable to SSL stripping attacks.
Insecure Cookies
Cookies without HttpOnly, Secure, and SameSite attributes are vulnerable to theft.
Information Disclosure
Server headers revealing version information or internal details.
Additional Resources
Security Headers Scanner
Scan your website's security headers and get improvement recommendations.
Visit Resource →