Add security headers in Nginx
Nginx sets response headers with the add_header directive. Put these inside your server block (or a shared include), and always use the always flag so the header is sent on error responses too:
server {
# ... your existing config ...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header X-XSS-Protection "0" always;
}
The add_header inheritance trap
Nginx does not merge add_header directives across blocks: if you add a header inside a location, every add_header from the parent server block stops applying in that location. Define your headers once at the server level, or repeat them in each location that sets its own.
Adding a Content Security Policy
CSP is powerful but site-specific. Start in report-only mode so you break nothing:
add_header Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'" always;
Once the reports are clean, switch the header name to Content-Security-Policy to enforce it. See the CSP setup guide for the nonce approach.
Reload and verify
nginx -t && systemctl reload nginx
Then scan your domain with HeaderTest to confirm every header is present and correctly valued. Per-header options: HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy.