HTTP Security Headers:A Simple Guide for Developers
Most security work takes time. Security headers do not. They are a few lines of configuration that turn on protections already built into every browser. Many apps ship without them simply because no one knew they existed. This guide explains the headers that matter, in plain words, and gives you a safe starting set you can copy.
What Are HTTP Security Headers?
Every time your server answers a request, it sends back headers: small pieces of information about the response. Security headers are the ones that tell the browser to switch on extra protection, such as blocking mixed content, refusing to be framed, or only running scripts you allow. The browser already knows how to do these things. The header is how your server asks it to.
Which Security Headers Matter Most?
You do not need every header that exists. These are the ones that give you the most protection for the least effort.
| Header | What it does |
|---|---|
| Content-Security-Policy | Controls which scripts, styles, and sources can load. The strongest single defence against cross site scripting. |
| Strict-Transport-Security | Tells browsers to always use HTTPS for your site, even if someone types http. |
| X-Content-Type-Options: nosniff | Stops the browser from guessing a file's type, which can turn an upload into a script. |
| X-Frame-Options | Stops other sites from putting your pages in a frame, which prevents clickjacking. |
| Referrer-Policy | Controls how much of your URL is shared when a user clicks a link away from your site. |
| Permissions-Policy | Turns off browser features you do not use, such as camera, microphone, and location. |
Two of these have their own full guides on this site, because they do a lot of work. For Content Security Policy, see our CSP guide. For Strict Transport Security and HTTPS, see HTTPS and TLS.
How Does Each Header Protect You?
- Content-Security-Policy lists the sources a page is allowed to load scripts and other content from. If an attacker injects a script, the browser refuses to run it because it is not on the list. It is the backstop for cross site scripting.
- Strict-Transport-Security (HSTS) makes the browser remember to always use HTTPS, so traffic cannot be quietly downgraded to plain text.
- X-Content-Type-Options: nosniff forces the browser to trust the type you set, so a file that claims to be an image cannot be run as a script.
- X-Frame-Options or the CSP frame-ancestors rule stops your pages being placed inside a hidden frame on another site, which is how clickjacking tricks users into clicking things they cannot see.
- Referrer-Policy limits how much of your address is passed to other sites, so private URLs and tokens in links do not leak.
- Permissions-Policy switches off powerful features you do not use, so a bug cannot turn on the camera, microphone, or location.
What Is a Good Starting Set?
Here is a safe, sensible set to start from. Test it on your app and adjust, because a strict Content Security Policy in particular may need tuning for the scripts you actually use.
Content-Security-Policy: default-src 'self'
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()
How Do You Check Your Headers?
You do not have to guess. Free scanners read your live headers and grade them, so you can see what is missing in seconds.
- Run a free scan with the Mozilla HTTP Observatory.
- Compare your set against the OWASP Secure Headers Project, which lists each header and a safe value.
- Add headers to your whole app in one place: your server config, your framework, or your CDN.
What Are the Common Mistakes?
- Setting no headers at all. The most common mistake is simply not having them.
- A Content Security Policy that allows everything. A policy with unsafe-inline or a wildcard gives almost no protection. See the CSP guide for a strong policy.
- HSTS with preload before you are ready. Preload is hard to undo, so only add it once your whole site works over HTTPS.
- Setting headers on some pages only. Apply them to every response, including errors and redirects.