Security headers on IIS and Nginx: HSTS, CSP and the ones that matter
Add HSTS, CSP, nosniff, frame protection and Referrer-Policy with IIS/Nginx, test them, and avoid breaking the app with a copied CSP.
- Build
- 26100.33650
- Edition
- Standard / Datacenter
- Architecture
- x64
- Support
- Documentation (E1)
- Evidence
- E1Official documentation
- Verified
- 2026-10-29
- Page type
- Task
The short answer
Section titled “The short answer”Start with headers that rarely break apps:
Strict-Transport-Security: max-age=31536000; includeSubDomainsX-Content-Type-Options: nosniffReferrer-Policy: strict-origin-when-cross-originContent-Security-Policy: frame-ancestors 'self'Add a full CSP only after inventorying scripts/styles/frames. A copied CSP will break the app and get removed.
web.config:
<system.webServer> <httpProtocol> <customHeaders> <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" /> <add name="X-Content-Type-Options" value="nosniff" /> <add name="Referrer-Policy" value="strict-origin-when-cross-origin" /> <add name="Content-Security-Policy" value="frame-ancestors 'self'" /> <remove name="X-Powered-By" /> </customHeaders> </httpProtocol></system.webServer>IIS may add X-Powered-By; remove it. Do not add HSTS to HTTP responses; browsers ignore it, but it signals a config mistake.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;add_header X-Content-Type-Options "nosniff" always;add_header Referrer-Policy "strict-origin-when-cross-origin" always;add_header Content-Security-Policy "frame-ancestors 'self'" always;server_tokens off;always applies to error responses too.
- Only after every name on the host works over HTTPS.
includeSubDomainsaffects all subdomains; be sure.- Start with a short
max-agein a pilot; raising it is easy, rolling back is slow (browsers cache it). - Do not add
preloadunless you understand the removal process.
Use report-only first:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-reportThen enforce with nonces/hashes for inline scripts. frame-ancestors is the modern replacement for X-Frame-Options; keep XFO only for old clients if needed.
Verify
Section titled “Verify”curl.exe -I https://lab.example/curl.exe -I https://lab.example/assets/app.jsCheck headers on HTML, static assets and error pages. A header added only on 200 responses is incomplete.
Lab boundary
Section titled “Lab boundary”E1. The lab did not apply these headers or run a CSP report collector; the snippets are the starting point to validate on Server 2025.