SteadyHost

Security headers explained, with examples

Security headers are instructions your server sends along to the browser. They make well-known attacks, such as clickjacking and script injection, a lot harder. They're one layer of security: missing headers don't make a site insecure, and present headers don't prove it's secure.

Check your website now

The five headers SteadyHost checks

  • Strict-Transport-Security (HSTS): browsers will only open your site over HTTPS from then on. Only works if HTTPS works properly everywhere.
  • Content-Security-Policy (CSP): determines which sources scripts, styles and images may come from. The most powerful header against script injection (XSS).
  • X-Content-Type-Options: nosniff prevents browsers from interpreting files as a different type than the server specifies.
  • Referrer-Policy: determines how much of the current address is sent along to other websites.
  • Permissions-Policy: turns off browser features your site doesn't use, such as camera, microphone and location.

Inspect your headers yourself

With curl you can see which headers your server sends. Besides the homepage, check a few other pages too: headers set in one folder or in one part of the configuration don't always apply to the whole site.

Terminal
curl -sI https://example.com

Setting headers in nginx

Start with the headers that almost never break anything. These example values are safe for most websites.

nginx
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 Permissions-Policy "camera=(), geolocation=(), microphone=()" always;

Setting headers in Apache

If you use Apache, put the same headers in .htaccess. With a CDN such as Cloudflare, or with a hosting control panel, you can often do it through the settings as well.

.htaccess (Apache)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), geolocation=(), microphone=()"

Content-Security-Policy step by step

A Content-Security-Policy has to match the scripts, fonts and services your website uses (such as analytics, chat or a payment provider). A policy that's too strict breaks parts of your site.

So start with Content-Security-Policy-Report-Only: the browser then reports what it would block, without blocking anything. Only when there are no more unexpected reports do you actually enforce the policy.

Example of a strict CSP
Content-Security-Policy: default-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'; base-uri 'self'

What a header check doesn't tell you

A header check only looks at what the server tells the browser. It says nothing about outdated software or plugins, weak passwords, vulnerabilities in your website's code or the security of the server itself. For that you need updates, good maintenance and, where it matters, a security audit or penetration test.

How SteadyHost rates security headers

  • OK: all five headers are present.
  • Warning: some are missing. A CSP in report-only mode doesn't count as present yet, and HSTS only counts over HTTPS.
  • Problem: none of the five headers are present.
  • SteadyHost looks at the homepage and checks whether the headers are present, not whether a Content-Security-Policy is strict enough.

Check your own website

A free check shows within seconds how your website is doing: availability, HTTPS and TLS, the SSL certificate, security headers, DNS and DNSSEC, domain registration and email security.

More guides