HTTP Security Headers: HSTS, CSP, X-Frame-Options & OWASP Guide
HTTP response headers govern how modern web browsers parse, execute, and isolate web application assets. When configured correctly, security headers provide defense-in-depth protection against cross-site scripting (XSS), clickjacking, MIME-type sniffing, man-in-the-middle attacks, and unauthorized device access. Using the Whoistrackr HTTP Headers Audit, webmasters can verify response headers and identify missing security directives.
The 6 Essential OWASP Recommended Security Headers
| Header | Recommended Baseline Directive | Primary Risk Mitigated | Specification |
|---|---|---|---|
| Strict-Transport-Security | max-age=31536000; includeSubDomains; preload | SSL/TLS stripping, unencrypted plaintext HTTP downgrades, man-in-the-middle interception | RFC 6797 |
| Content-Security-Policy | default-src 'self'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; | Cross-Site Scripting (XSS), malicious script injection, data exfiltration | W3C CSP Level 3 |
| X-Content-Type-Options | nosniff | MIME-confusion attacks, non-executable content parsed as executable scripts/styles | RFC 7231 |
| X-Frame-Options | DENY or SAMEORIGIN | Clickjacking, hidden transparent iframe overlays, unauthorized UI redressing | RFC 7034 |
| Referrer-Policy | strict-origin-when-cross-origin | Leaking sensitive URL paths, tokens, or query parameters in the Referer header to 3rd-party origins | W3C Referrer Policy |
| Permissions-Policy | camera=(), microphone=(), geolocation=(), payment=() | Unauthorized browser API access, unconsented hardware access (camera/mic/GPS) in nested frames | W3C Permissions Policy |
Deep Dive: Core Security Directives
1. HTTP Strict Transport Security (HSTS)
HSTS informs client browsers that the domain must only ever be accessed using HTTPS. When a browser receives an HSTS header, it transforms all future insecure http:// links to https:// locally before sending any network traffic.
- max-age: Specifies the duration in seconds that the browser must remember the HTTPS-only policy (
31536000corresponds to 1 full year). - includeSubDomains: Applies the HTTPS enforcement policy recursively to all present and future subdomains.
- preload: Authorizes inclusion in the Chromium/Firefox/WebKit hardcoded HSTS preload list, protecting first-time visitors before any initial network request is dispatched.
2. Content Security Policy (CSP)
Content Security Policy is the primary client-side defense against Cross-Site Scripting (XSS). By declaring an allowlist of trusted origin domains and cryptographic nonces or hashes, the browser halts execution of unauthorized inline scripts and external payloads:
default-src 'self': Disallows loading arbitrary remote assets unless explicitly permitted by specialized directives.object-src 'none': Prevents loading legacy Flash or Java applet plugins.base-uri 'self': Restricts the URLs that can appear in a document's<base>element, preventing base-tag injection attacks.frame-ancestors 'none': Modern CSP replacement forX-Frame-Options: DENY, controlling which domains may embed the page.
3. MIME Sniffing Defense (X-Content-Type-Options)
Some legacy browsers attempt to inspect ("sniff") the byte stream of an asset to guess its MIME type rather than respecting the server's declared Content-Type header. An attacker could exploit this by uploading an image containing JavaScript and tricking the browser into executing it. The nosniff directive forces browsers to strictly honor the declared MIME type.
Server Configuration Snippets
Webmasters can implement these recommended headers directly at the web server or CDN level:
Apache (.htaccess or VirtualHost)
<IfModule mod_headers.c> Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()" </IfModule>
Nginx (nginx.conf)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Caddy (Caddyfile)
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "camera=(), microphone=(), geolocation=()"
}