Security Headers
Status: Complete
Category: Security
Default enforcement: Soft
Author: PushBackLog team
Tags
- Topic: security
- Skillset: backend, frontend, devops
- Technology: generic
- Stage: execution, review
Summary
HTTP security headers are server-side declarations that instruct browsers and intermediaries how to handle the content of a response. They provide defence-in-depth against cross-site scripting (XSS), clickjacking, MIME-type sniffing, protocol downgrade attacks, and information leakage. Most can be configured once at the web server or API gateway level and then apply globally. Omitting them is a low-cost, high-impact vulnerability that automated scanners detect and report.
Rationale
Security headers are cheap to deploy and valuable to have
A properly configured Content-Security-Policy header reduces the exploitability of XSS vulnerabilities by restricting which scripts the browser will execute. An X-Frame-Options header prevents clickjacking. Strict-Transport-Security prevents protocol downgrade attacks. These protections do not require application code changes — they are HTTP responses headers that can usually be set at the reverse proxy or CDN level.
Not deploying them is leaving available security controls unused, which OWASP classifies under A02 (Security Misconfiguration).
Guidance
Essential security headers
Content-Security-Policy (CSP)
The most powerful and most complex security header. CSP tells the browser which sources it may load scripts, styles, images, and other resources from. A strict CSP makes XSS attacks significantly harder to exploit.
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-{RANDOM_NONCE}';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' https://api.example.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
Start with CSP in report-only mode (Content-Security-Policy-Report-Only) to identify violations before enforcing:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
Strict-Transport-Security (HSTS)
Instructs browsers to only access the site via HTTPS, preventing protocol downgrade attacks:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age=31536000— 1 year; start with a shorter value and increase once stableincludeSubDomains— applies to all subdomainspreload— submit to browser preload lists (browsers will refuse HTTP before ever connecting)
X-Frame-Options
Prevents the page from being embedded in an <iframe> (clickjacking protection):
X-Frame-Options: DENY
Use frame-ancestors 'none' in CSP for newer browsers (CSP takes precedence), but keep X-Frame-Options for older browser compatibility.
X-Content-Type-Options
Prevents browsers from MIME-sniffing the response content type:
X-Content-Type-Options: nosniff
Referrer-Policy
Controls how much referrer information is included with requests:
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy
Controls which browser features the page can use:
Permissions-Policy: camera=(), microphone=(), geolocation=(self), payment=(self)
Cross-Origin headers
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-site
These isolate the browsing context and protect against Spectre-class side-channel attacks.
Headers to remove (information disclosure)
# Remove these — they leak server implementation details
X-Powered-By: (remove entirely)
Server: (remove or set to a generic value: "Server: web")
X-AspNet-Version: (remove)
Implementation in Node.js (Helmet)
import helmet from 'helmet';
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.nonce}'`],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'", process.env.API_URL!],
frameAncestors: ["'none'"],
objectSrc: ["'none'"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
})
);
Verification tools
- securityheaders.com — grade and full header analysis for any URL
- Mozilla Observatory — comprehensive security header check
- OWASP ZAP — automated scan includes header checks
- Helmet audit in CI:
npx helmet-csp-check
Review checklist
-
Content-Security-Policyis present and restricts script sources -
Strict-Transport-Securityis set with a minimum 6-monthmax-age -
X-Frame-Options: DENYorframe-ancestors 'none'in CSP is set -
X-Content-Type-Options: nosniffis set -
Referrer-Policyis set -
X-Powered-ByandServerheaders do not reveal implementation details - Headers verified with securityheaders.com or equivalent before production