ServerNeed — This Year's Best Offers For You

ServerNeed — More Than Hosting
Security

HTTP Security Headers Explained:CSP, HSTS and More

The HTTP security headers worth setting (HSTS, Content-Security-Policy, X-Content-Type-Options, Referrer-Policy, Permissions-Policy and frame protection), what each prevents and how to roll them out safely.

5 min read
Lifeguard tower on a beach
Table of Contents
  1. The headers at a glance
  2. Strict-Transport-Security (HSTS)
  3. Content-Security-Policy (CSP)
  4. X-Content-Type-Options
  5. Referrer-Policy
  6. Permissions-Policy
  7. Clickjacking protection
  8. Where to set headers
  9. How to check
  10. Example: setting headers on Apache, LiteSpeed and Nginx
  11. Rolling out CSP on a WordPress site
  12. Frequently Asked Questions
  13. Related reading
  14. Sources

HTTP security headers are instructions a website sends to the browser that turn on built-in protections: forcing HTTPS, restricting which scripts can run, stopping the page being framed by other sites, and limiting what information and features are exposed. The most useful are Strict-Transport-Security (HSTS), Content-Security-Policy (CSP), X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and frame protection (frame-ancestors in CSP, or X-Frame-Options).

They cost little to add, but some (HSTS and CSP especially) need careful rollout to avoid breaking the site.

The headers at a glance

Header Protects against Typical value
Strict-Transport-Security Downgrade to HTTP, cookie theft over HTTP max-age=31536000; includeSubDomains
Content-Security-Policy Cross-site scripting, content injection, clickjacking A policy listing allowed sources
X-Content-Type-Options MIME-type sniffing attacks nosniff
Referrer-Policy Leaking full URLs to other sites strict-origin-when-cross-origin
Permissions-Policy Unwanted access to camera, microphone, location and other features camera=(), microphone=(), geolocation=()
X-Frame-Options / CSP frame-ancestors Clickjacking (your page framed by another site) DENY / frame-ancestors 'none'

Strict-Transport-Security (HSTS)

HSTS tells browsers to use HTTPS for your domain for a period, even if someone types http:// or follows an HTTP link.

Roll out carefully:

  1. Make sure the whole site, and every subdomain if you use includeSubDomains, works over HTTPS.
  2. Start with a short max-age (for example 300 seconds), then increase it gradually to a year.
  3. Consider the preload list only when you are certain, because removal takes a long time.

See what is SSL/TLS and how does HTTPS work.

Content-Security-Policy (CSP)

CSP lists where scripts, styles, images, fonts, frames and connections may come from. If an attacker injects a script, the browser refuses to run it unless it matches the policy. A simple starting policy:

Content-Security-Policy: default-src 'self'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'

Real sites usually need to allow analytics, payment providers, fonts and other third parties. Practical advice:

  • Start with Content-Security-Policy-Report-Only to see what would be blocked without breaking anything.
  • Avoid 'unsafe-inline' and 'unsafe-eval' for scripts where possible; use nonces or hashes for inline scripts.
  • Add sources deliberately, not with wildcards like *.
  • Tighten the policy step by step.

X-Content-Type-Options

nosniff stops browsers from guessing a file's type and, for example, executing an uploaded text file as a script. It is safe to enable everywhere.

Referrer-Policy

Controls how much of the current URL is sent when a visitor follows a link to another site. strict-origin-when-cross-origin sends only the origin to other sites over HTTPS and keeps full paths (which may contain identifiers) private. It is also the default in modern browsers.

Permissions-Policy

Disables browser features your site does not use, such as camera, microphone or geolocation, reducing what injected or third-party code could abuse.

Clickjacking protection

Stop other sites from loading your pages inside a frame to trick users into clicking: use CSP frame-ancestors 'none' (or 'self'), and X-Frame-Options: DENY for older browsers.

Where to set headers

  • Web server configuration (Apache, Nginx, LiteSpeed) or .htaccess on shared hosting.
  • Your application or framework, which can set headers per response (useful for CSP nonces).
  • A CDN or proxy, which can add headers at the edge.

Avoid setting the same header in two places with different values.

How to check

Use your browser's developer tools (Network tab → response headers) or an online header scanner, and test important pages after every change.

Example: setting headers on Apache, LiteSpeed and Nginx

Apache or LiteSpeed (.htaccess or server configuration), with mod_headers:

<IfModule mod_headers.c>
  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=(), microphone=(), geolocation=()"
  Header always set X-Frame-Options "DENY"
</IfModule>

Nginx (inside the server block):

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=(), microphone=(), geolocation=()" always;
add_header X-Frame-Options "DENY" always;

Note that in Nginx, add_header directives in a location block replace those inherited from the server block, so headers can silently disappear on some paths. Check several URLs after configuring.

Add the Content-Security-Policy separately, starting in report-only mode, because it needs tailoring to each site.

Rolling out CSP on a WordPress site

  1. Start with Content-Security-Policy-Report-Only and a basic policy.
  2. Browse the site, including admin and checkout, and read the console reports.
  3. Add the sources the site genuinely needs: analytics, payment providers, fonts, embedded videos.
  4. Keep inline scripts to a minimum; many plugins add them, which is the main obstacle to a strict policy.
  5. Switch to the enforcing header once reports are clean, and keep monitoring.

For WordPress hardening beyond headers, see the WordPress security checklist, and for the bigger picture of protecting applications, OWASP Top 10 explained.

Frequently Asked Questions

Can security headers break my site?

HSTS and CSP can, if rolled out too aggressively. Use report-only mode for CSP and short HSTS durations at first.

Is X-XSS-Protection still useful?

No. Modern browsers have removed the old XSS filter it controlled; use CSP instead.

Do headers replace secure coding?

No. They limit damage when something goes wrong; validating input and escaping output remain essential.

Headers are part of secure configuration in website security basics. For applications built with security in mind, see ServerNeed custom web development.

Sources

Last updated 7 October 2026

View All Articles