Contents
Running a production API without properly configured HTTP headers is leaving your front door unlocked. Browsers block modern features, CDNs refuse to cache your responses and attackers can exploit XSS, clickjacking and CSRF vulnerabilities in seconds.
This is the definitive guide to HTTP headers; from security headers that stop attacks to performance headers that make your app faster, with production-ready Node.js code examples.

Why HTTP Headers Are Critical?
| Risk | Without Proper Headers | With Proper Headers |
|---|---|---|
| Security | XSS, clickjacking, CSRF attacks possible | CSP, HSTS, COOP block exploitation |
| Performance | Every request hits origin | CDN caches, 304 responses save bandwidth |
| Browser Features | WebAuthn, Service Workers blocked | Permissions-Policy enables features |
| CORS Issues | Cross-origin API calls fail | Proper headers enable secure CORS |
| Cache Efficiency | Assets re-downloaded on every page load | Long-lived cache with versioning |
| Compliance | PCI-DSS, GDPR violations | Security headers demonstrate compliance |
Bottom line: HTTP headers are not optional; they’re the foundation of web security and performance. If your API is missing these headers, you’re inviting attacks and wasting resources.
What Are HTTP Headers?
HTTP headers are key-value pairs sent between clients and servers that pass additional context and metadata about requests and responses. They control security, caching, content negotiation and more.
| Header Type | Location | Purpose | Examples |
|---|---|---|---|
| Request Headers | Client → Server | Describe the request | User-Agent, Accept, Authorization |
| Response Headers | Server → Client | Describe the response | Content-Type, Set-Cookie, Server |
| Representation Headers | Both | Describe the body | Content-Type, Content-Encoding |
| Payload Headers | Both | Transport info | Content-Length, Transfer-Encoding |
In Simple Words
HTTP headers are the metadata packets that travel with your actual data.
Think of it like sending a package:
HTTP body = the package contents HTTP headers = the shipping label (address, handling instructions, weight, priority)
Headers tell browsers and intermediaries how to handle, cache, secure and interpret the content they receive.
Security Headers: Stopping Attacks Before They Happen
Content-Security-Policy (CSP)
| Header Value | What It Does | Protection Level |
|---|---|---|
default-src 'self' |
Only load from same origin | Base protection |
script-src 'nonce-random' |
Inline scripts must have nonce | XSS protection |
object-src 'none' |
Block plugins (Flash, PDF) | Plugin-based attacks |
upgrade-insecure-requests |
Force HTTPS on all resources | MiTM prevention |
|
|
One-liner:
CSP is your primary defense against XSS attacks.
Start with strict'self'policy and only add exceptions as needed. Test withContent-Security-Policy-Report-Onlybefore enforcing.
Strict-Transport-Security (HSTS)
| Parameter | Value | Purpose |
|---|---|---|
max-age |
63072000 (2 years) |
Force HTTPS duration |
includeSubDomains |
true |
Apply to all subdomains |
preload |
true |
Add to browser preload list |
|
|
Critical warning: Never set long max-age or preload in development; you’ll lock yourself out of localhost.
One-liner:
HSTS forces HTTPS-only connections for your domain.
Once your site is fully HTTPS, add this header. Once on preload list, removal is nearly impossible.
Cross-Origin Isolation Headers (COOP + COEP)
| Header | Value | Enables |
|---|---|---|
Cross-Origin-Opener-Policy |
same-origin |
Process isolation |
Cross-Origin-Embedder-Policy |
require-corp |
Cross-origin resource control |
Cross-Origin-Resource-Policy |
same-origin |
Resource access control |
|
|
Required for: SharedArrayBuffer, precise performance.now(), high-resolution timers and advanced Web APIs.
X-Frame-Options
| Value | Behavior |
|---|---|
DENY |
Block all framing |
SAMEORIGIN |
Allow same-site only |
ALLOW-FROM uri |
Deprecated, ignored |
|
|
Note: This is a legacy header. Prefer CSP’s frame-ancestors directive, but keep both for browser compatibility.
Essential Security Header Summary
| Header | Purpose | Recommended Value |
|---|---|---|
Content-Security-Policy |
XSS protection | default-src 'self'; object-src 'none' |
Strict-Transport-Security |
HTTPS enforcement | max-age=63072000; includeSubDomains; preload |
X-Content-Type-Options |
MIME sniffing protection | nosniff |
X-Frame-Options |
Clickjacking protection | DENY |
Referrer-Policy |
Privacy | strict-origin-when-cross-origin |
Permissions-Policy |
Feature control | geolocation=(), camera=(), microphone=() |
Cross-Origin-Resource-Policy |
Resource protection | same-origin |
CORS Headers: Enabling Secure Cross-Origin Requests
| Header | Purpose | Best Practice |
|---|---|---|
Access-Control-Allow-Origin |
Allowed origins | Exact URL, not * |
Access-Control-Allow-Methods |
Allowed HTTP methods | Only needed methods |
Access-Control-Allow-Headers |
Allowed request headers | Only needed headers |
Access-Control-Allow-Credentials |
Enable cookies | true only with specific origin |
Access-Control-Max-Age |
Preflight cache duration | 86400 (1 day) |
Production-Grade CORS Configuration
|
|
One-liner:
Never use
Access-Control-Allow-Origin: *withcredentials: true.
This causes browser errors. Always specify exact origins when using cookies or auth headers.
Manual CORS Setup (Without Middleware)
|
|
Performance Headers: Caching and Content Delivery
| Header | Use Case | Recommended Value |
|---|---|---|
Cache-Control |
Asset caching | public, max-age=31536000, immutable |
ETag |
Cache validation | Content hash (strong) |
Last-Modified |
Fallback validator | Timestamp of last change |
Vary |
Cache key variation | Vary: Accept-Encoding |
Content-Encoding |
Compression | br (Brotli) or gzip |
Cache-Control Strategies by Content Type
| Content Type | Cache Strategy | Value |
|---|---|---|
| Static assets (JS, CSS) | Long-term cache | public, max-age=31536000, immutable |
| HTML | Short validation | public, max-age=0, must-revalidate |
| API responses | Conditional caching | public, max-age=60, s-maxage=300 |
| Sensitive data | No cache | no-store, no-cache, must-revalidate |
Production Caching Setup
|
|
One-liner:
Version your static assets (e.g., main.abc123.js) and cache them for a year.
When content changes, update the hash. This forces browsers to fetch the new version while keeping long cache times.
Compression Headers
|
|
Cookie Security Headers
| Attribute | Purpose | Recommended Value |
|---|---|---|
HttpOnly |
Prevent JavaScript access | true for session cookies |
Secure |
HTTPS only | true in production |
SameSite |
CSRF protection | Strict or Lax |
Path |
Cookie scope | / for entire site |
Domain |
Subdomain access | Only if needed |
Production Cookie Setup
|
|
One-liner:
Always set
HttpOnlyon session cookies to block XSS attacks.
Never send sensitive cookies over non-HTTPS connections. In production,Secureis non-negotiable.
Complete Production-Ready Setup
|
|
Common Pitfalls and How to Avoid Them
| Pitfall | Why It’s Bad | Fix |
|---|---|---|
Access-Control-Allow-Origin: * with credentials |
Browser blocks requests | Use specific origin URL |
Missing Vary: Origin with dynamic CORS |
CDN serves wrong response | Add Vary: Origin header |
unsafe-inline in CSP |
Defeats XSS protection | Use nonce or hash-based CSP |
| Long HSTS max-age in dev | Locks you out of localhost | Only set in production |
| Cache-Control on sensitive data | Data leaks via shared cache | Use no-store, no-cache |
| SameSite=None without Secure | Browser rejects cookie | Always use with Secure flag |
| Missing ETag on dynamic content | Inefficient revalidation | Generate content-based ETags |
X-Powered-By: Express |
Reveals tech stack | Remove with helmet.hidePoweredBy() |
Deployment Checklist (Before You Go Live)
- Security Headers: CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy
- Cross-Origin Isolation: COOP + COEP if using SharedArrayBuffer
- CORS: Specific origins (not
*), proper methods/headers,Vary: Origin - Caching: Cache-Control by content type, ETags for validation
- Compression: Brotli or gzip enabled,
Vary: Accept-Encoding - Cookies: HttpOnly + Secure + SameSite on all auth cookies
- HTTPS: SSL/TLS 1.2+, HSTS enabled
- Testing: Test with https://securityheaders.com and https://observatory.mozilla.org
- Monitoring: Log CSP violations and CORS errors
Final Thoughts
In today’s world, “We’ll configure headers later” is no longer acceptable.
- Modern browsers require security headers for advanced features
- Proper caching dramatically reduces server load and latency
- CORS misconfigurations silently break cross-origin functionality
- Header-based attacks are trivial to exploit without proper defenses
Configure your headers today. Your security team, your users and your performance metrics will thank you.
