Web Security Headers: Seven Headers That Close Doors Attackers Walk Through

Seven HTTP headers close common holes like session theft, clickjacking, and running malicious scripts, with a few lines added to your Nginx config. We give the full example, how to test it, and a safe path to enable CSP without breaking your site.
Security headers are instructions you send in the HTTP response to tell the browser how to protect your user from common attacks. By adding seven headers to your Nginx config you close real doors attackers walk through: session theft over an unencrypted connection, embedding your site in a malicious frame to trick the user (clickjacking), running injected scripts (XSS), and leaking information in the referrer header. Best of all, this is added in a few lines with no change to your code, and its effect shows immediately in assessment tools.
The direct answer: the seven headers are Strict-Transport-Security to enforce HTTPS, Content-Security-Policy to restrict content sources, X-Frame-Options to block framing, X-Content-Type-Options to stop file-type guessing, Referrer-Policy to control referrer leakage, Permissions-Policy to restrict browser capabilities, and Cross-Origin-Opener-Policy to isolate your window. The riskiest is CSP because it is the strongest and the most likely to break the site if enabled all at once, which is why we explain its safe rollout at the end.
Here we cover each header and its role, then give a full Nginx config example, how to test your site with assessment tools, the real effect of the headers, and finally the safe path to enable CSP without breaking anything.
A real attack scenario that shows the value
Imagine a company's internal app managing customer data, with no security headers. The attacker starts by injecting a script into a comment field that is not sanitized well, so the script runs in the browser of every employee who opens the page, steals the session cookie, and sends it to the attacker's server. With a tuned Content-Security-Policy, the browser refuses to run the injected script from an unauthorized domain, and the chain breaks at the first step. If the attacker succeeds another way, Strict-Transport-Security stops them from intercepting the session over an unencrypted connection on a public network, and X-Frame-Options stops them from framing the login interface inside a phishing site that tricks the employee. Each header closes a link in the attack chain, and together they make exploiting a single vulnerability much harder. This is the essence of defense in depth: do not rely on one barrier, place successive barriers where the attacker stumbles again and again.
The seven headers and each one's role
1. Strict-Transport-Security
It forces the browser to use HTTPS exclusively for your site for a set period, so even if the user types http, the browser converts it automatically before any request. This closes first-connection interception and session-cookie theft over an unsafe network.
2. Content-Security-Policy
It tells the browser which sources are allowed to load content (scripts, styles, images). If an attacker injects a malicious script from an unauthorized domain, the browser refuses to run it. This is the strongest header against XSS, and the one that needs the most care when tuning.
3. X-Frame-Options
It prevents your page from being embedded in a frame on another site, closing clickjacking attacks where the attacker tricks the user into clicking hidden elements over your real interface.
4. X-Content-Type-Options
It stops the browser from guessing a file type other than what you declared, closing holes that trigger when an uploaded file treated as an image is executed as a script.
5. Referrer-Policy
It controls how much information is sent in the referrer header when a user moves from your page to another, preventing internal paths or sensitive identifiers in the URL from leaking to external sites.
6. Permissions-Policy
It restricts the page's access to browser capabilities such as camera, microphone, and geolocation, shrinking the blast radius if your page is compromised, since a malicious script cannot enable capabilities you already disabled.
7. Cross-Origin-Opener-Policy
It isolates your site's window from windows of other origins, preventing a class of leak attacks through shared windows. It is a modern header that completes the cross-origin isolation set.
A full Nginx config example
These directives are added inside the server block in the Nginx config, so they apply to every response. The table shows each header and the recommended value as a safe start:
| Header | Recommended value (start) |
|---|---|
| Strict-Transport-Security | max-age=31536000; includeSubDomains |
| X-Frame-Options | DENY |
| X-Content-Type-Options | nosniff |
| Referrer-Policy | strict-origin-when-cross-origin |
| Permissions-Policy | camera=(), microphone=(), geolocation=() |
| Cross-Origin-Opener-Policy | same-origin |
| Content-Security-Policy | default-src 'self' (start in report mode first) |
Each header is written with an add_header directive inside the server block, noting that HSTS with a full year (31536000 seconds) should only be enabled after confirming HTTPS works on all subdomains, since the browser will refuse any unencrypted connection for the whole period. After saving, reload Nginx to apply the config immediately. If your site runs on a cloud server, you have full access to the Nginx config and apply this directly.
Testing your site with assessment tools
After applying, scan your site with a security-headers assessment tool that gives you a grade from A to F with a list of what you are missing. These tools are free and scan your site in one request, revealing at once any missing or weakly set header. The realistic target is a grade of A or higher, entirely achievable with the seven headers above and a tuned CSP. Rescan after every change to make sure you did not break anything, since periodic scanning is part of site hygiene, not a one-time step you run and forget.
The real effect of the headers and its limits
It is important to be precise: headers are a supplementary defense layer, not a substitute for secure code. X-Frame-Options prevents clickjacking almost completely, and HSTS strongly closes the connection-interception class. CSP, however, is a strong mitigation of XSS impact, not absolute immunity from it, because it reduces what an attacker can execute after injection but does not replace input sanitization and output encoding in your code. The rule: apply headers as a layer, and write secure code as the foundation, since both layers together close most of the doors.
The safe rollout of CSP
CSP is the only header that may break your site if enabled strictly all at once, because it can block scripts or styles your site actually depends on. The safe way is gradual:
- Start in report mode: enable the version that only reports without blocking, so the browser logs what it would have blocked without breaking anything, and you review the reports to learn your real sources.
- Review the reports for a week: gather every source your site actually uses (scripts, fonts, images from external domains) and add them to the policy.
- Tighten gradually: start with a broad policy then narrow it step by step, avoiding unconditional allowances that empty the header of value.
- Switch to enforcement: after two weeks of clean reports, move from report mode to actual enforcement, and keep watching for any breakage.
This progression gives you CSP protection without the surprise of breaking the site in front of your users, and that is the difference between a successful rollout and an embarrassing rollback.
Common mistakes when applying
Some mistakes empty the headers of value or break the site, and avoiding them saves you time:
- Enabling HSTS before HTTPS is ready: if you enable HSTS for a year then find a subdomain without a certificate, the browser will refuse to reach it for the whole period. First confirm all your subdomains work on HTTPS, then consider adding them to the browsers' built-in preload list only after full stability.
- A loose CSP policy: unconditionally allowing every source makes the header exist on paper only with no real protection, since the value is in the restriction, not the presence.
- Forgetting to rescan: applying the headers once then neglecting them is a mistake, because site updates can break CSP or add new sources that need tuning.
- Duplicating a header: adding the same header in more than one place in the config can produce two conflicting values that the browser handles unpredictably, so keep each header in one clear place.
Conclusion: the steps to apply
Start today with the six simple headers (all except CSP), which are safe, added in minutes, and raise your grade immediately. Scan your site with the assessment tool and confirm they all appear. Then run CSP in report mode for two weeks, review, tighten, and switch to enforcement. Rescan after every step. The result is a site that closes doors attackers used to walk through, with no change to your code. If you run your site on cloud hosting or a cloud server, apply the config directly and watch its effect in the tool's grade.


