Nginx Security Headers (CSP, HSTS, X-Frame)
Add essential browser security headers in Nginx including Content-Security-Policy, Strict-Transport-Security HSTS, X-Frame-Options, and more headers.
Detailed Explanation
Security headers instruct browsers to enable built-in protections against common web attacks like cross-site scripting, clickjacking, and MIME type sniffing. Adding them at the Nginx level ensures every response includes these protections consistently.
Essential Security Headers
server {
# Prevent clickjacking by restricting iframe embedding
add_header X-Frame-Options "SAMEORIGIN" always;
# Prevent MIME type sniffing attacks
add_header X-Content-Type-Options "nosniff" always;
# Enable browser XSS filter (for legacy browsers)
add_header X-XSS-Protection "1; mode=block" always;
# Control how much referrer information is shared
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Restrict access to browser features and APIs
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
}
Strict-Transport-Security (HSTS)
HSTS instructs browsers to always use HTTPS for your domain, which effectively prevents SSL stripping and protocol downgrade attacks:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
The max-age value is specified in seconds (63072000 equals approximately 2 years). The includeSubDomains flag extends HSTS protection to all subdomains. The preload flag qualifies your domain for inclusion in browser preload lists, but only add it after thorough testing because removal from preload lists is a slow and difficult process.
Content-Security-Policy (CSP)
CSP is the most powerful and flexible security header available. It defines precisely which sources of content are permitted, effectively mitigating cross-site scripting and data injection attacks:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; frame-ancestors 'self';" always;
Start with Content-Security-Policy-Report-Only during development to identify policy violations without breaking any existing functionality on your site.
The always Parameter
Without the always parameter, the add_header directive only applies to responses with 2xx and 3xx status codes. Adding always ensures security headers are present on error pages as well, preventing information leakage through unprotected error responses.
Header Inheritance Gotcha
A critical Nginx behavior: when you use add_header inside a location block, it completely replaces all headers defined in the parent server block. If you need to add location-specific headers, you must redeclare all server-level security headers in that location block as well, or use the third-party ngx_headers_more module.
Verification
Use browser developer tools or online scanning services like securityheaders.com to verify your security headers are correctly applied across all pages, including error responses.
Use Case
You are hardening your web application against common attacks by adding browser-enforced security policies that prevent clickjacking, XSS, and unauthorized content loading.