RestingOwl owl logo RestingOwl

HTTP Security Headers:A Simple Guide for Developers

Quick Answer: HTTP security headers are small settings your server sends with every response that tell the browser how to behave safely. A handful of them stop whole classes of attacks: Content Security Policy limits which scripts can run, Strict Transport Security forces HTTPS, X-Content-Type-Options stops file type guessing, X-Frame-Options stops your site being framed for clickjacking, and Referrer-Policy and Permissions-Policy control what leaks and which browser features pages can use. They are free to add and are one of the highest value, lowest effort security wins you can make.

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.

HeaderWhat it does
Content-Security-PolicyControls which scripts, styles, and sources can load. The strongest single defence against cross site scripting.
Strict-Transport-SecurityTells browsers to always use HTTPS for your site, even if someone types http.
X-Content-Type-Options: nosniffStops the browser from guessing a file's type, which can turn an upload into a script.
X-Frame-OptionsStops other sites from putting your pages in a frame, which prevents clickjacking.
Referrer-PolicyControls how much of your URL is shared when a user clicks a link away from your site.
Permissions-PolicyTurns 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.

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.
Related reading: Headers work best with the controls behind them. See Content Security Policy, HTTPS and TLS, CSRF protection, and secure cookies for the full browser security picture. You can also check your setup with the free OWASP toolkit.

References

  1. 1OWASP Secure Headers Project
  2. 2MDN: HTTP headers
  3. 3Mozilla HTTP Observatory

Q&A Section

They are small settings your server sends with every response that tell the browser to switch on extra protection. Examples include Content Security Policy, which limits which scripts can run, and Strict Transport Security, which forces HTTPS. The browser already knows how to do these things; the header is how your server asks it to.
The highest value ones are Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, and Permissions-Policy. Together they defend against cross site scripting, downgrade attacks, file type confusion, clickjacking, information leaks, and misuse of browser features. Content Security Policy does the most work and is worth the most tuning.
A strong Content Security Policy is a powerful backstop against cross site scripting, because it stops the browser running scripts that are not on your allowed list. It does not replace safe output handling, though. You still need to encode what you output. Think of headers and output encoding as two layers that work together.
No. They are usually a few lines of configuration in your server, framework, or CDN, applied to every response. The one that needs care is Content Security Policy, because a strict policy can block scripts your own app uses, so test it and tune it. The rest can often be added safely straight away.
Use a free scanner such as the Mozilla HTTP Observatory, which reads your live headers and grades them, and compare your set against the OWASP Secure Headers Project, which lists each header with a safe value. Both show you exactly what is missing so you can fix it quickly.
Copied!