In short: Security headers are lines that the web server sends with every response. They tell the browser, for example, to use only HTTPS, not to load third-party scripts, or not to display the page inside a foreign frame. The most important ones are Strict-Transport-Security (HSTS), Content-Security-Policy (CSP), X-Content-Type-Options, Referrer-Policy and Permissions-Policy. Introduce HSTS and CSP step by step; otherwise, in the worst case, you lock out your own visitors.
What are HTTP security headers?
When a browser requests a page, the server sends a few lines of extra information before the actual content. These HTTP headers contain things like the file type or caching details. Some of them serve security: they set rules that the browser follows. In this way, security headers protect visitors from attacks such as cross-site scripting (XSS) or clickjacking.
Headers don't replace updates or clean code. They are an extra layer of protection that achieves a lot with little effort. The OWASP Secure Headers Project collects recommendations on this. In the OWASP Top 10:2025, a missing header falls under the Security Misconfiguration category, which ranks at number 2 there.
Strict-Transport-Security (HSTS)
HSTS tells the browser: only access this domain via HTTPS. If a visitor later types http:// or clicks an old link, the browser switches to the encrypted connection on its own. An attacker on the same Wi-Fi network can then no longer intercept the connection unencrypted.
Strict-Transport-Security: max-age=31536000; includeSubDomainsmax-age sets how many seconds the browser remembers the rule; 31536000 equals one year. includeSubDomains extends the rule to all subdomains. According to MDN, the header only takes effect when it is delivered over HTTPS.
Introduce it step by step
First check whether every subdomain really supports HTTPS, including old ones such as a test system or a webmail portal. The operators of the HSTS preload list recommend increasing max-age gradually: first 300 seconds (five minutes), then 604800 (one week), then 2592000 (30 days). Only once everything works should you move to one year. If something goes wrong, set max-age=0 so that browsers forget the rule again.
Be careful with preload
With the preload directive and a submission at hstspreload.org, your domain ends up on a list that is built into browsers. You need a max-age of at least 31536000 and includeSubDomains for this. The catch: inclusion is hard to undo, and removal takes months. Only use preload once you are sure that the whole domain will use HTTPS permanently.

Content-Security-Policy (CSP)
The Content Security Policy defines from which sources the browser may load scripts, images, fonts and other resources. If an attacker injects a foreign script, the browser blocks it because its source has not been approved. This makes CSP an effective extra layer of protection against XSS. A simple example:
Content-Security-Policy: default-src 'self'; img-src 'self' https://cdn.example.com; frame-ancestors 'none'; upgrade-insecure-requestsThis policy allows content only from your own domain, with images also allowed from a CDN. It forbids embedding the page in foreign frames and makes the browser switch HTTP addresses to HTTPS automatically.
Test mode first
A CSP is often tricky, because modern websites include many third-party services: analytics, maps, videos, fonts, cookie banners. WordPress sites with lots of plugins in particular add up quickly. MDN recommends starting with the Content-Security-Policy-Report-Only header. With it, the browser blocks nothing but reports every violation in the console. You can see which sources are missing, add them to the policy and only then switch it to enforcement.
X-Frame-Options and frame-ancestors
In clickjacking, an attacker loads your website invisibly in an iframe on their own page. Visitors think they are clicking on something harmless and actually trigger an action on your site. The older X-Frame-Options header prevents this:
X-Frame-Options: SAMEORIGINWith DENY, nobody may embed the page; with SAMEORIGIN, only your own domain may. More comprehensive is the CSP directive frame-ancestors. Its value 'none' works roughly like DENY, and you can also allow individual domains. According to MDN, frame-ancestors does not work in a <meta> tag, only as a real header. Many sites send both variants so that older browsers are protected too.

Other important headers
X-Content-Type-Options
X-Content-Type-Options: nosniffThe value nosniff stops the browser from guessing the file type itself (MIME sniffing). Instead, it sticks to the type the server specifies. This means an uploaded text file won't suddenly be executed as a script. The header has practically no side effects and belongs on every website.
Referrer-Policy
Referrer-Policy: strict-origin-when-cross-originWhen a visitor clicks a link to another website, the browser normally reveals where they came from. The Referrer-Policy controls how much of that is shared. With strict-origin-when-cross-origin, other sites only receive the domain, without the full path and any parameters. According to MDN, this is also the default value when no header is set. If you want to reveal even less, the value is no-referrer.
Permissions-Policy
Permissions-Policy: camera=(), microphone=(), geolocation=()This header defines which browser features the page and embedded content may use, such as camera, microphone, location or full screen. Empty brackets switch a feature off for everyone, while (self) allows it only for your own domain. The header used to be called Feature-Policy.
X-XSS-Protection
You'll still find this header in many old guides. It controlled an XSS filter that browsers have since removed. MDN advises using a Content-Security-Policy instead. If you do set it, use the value 0.
Where to set security headers
That depends on how your website runs:
- Web server: On Apache, you can do this in the server configuration or in .htaccess, for example with
Header always set X-Content-Type-Options "nosniff". For nginx, theadd_headerdirective does the job. - CDN or proxy: Many content delivery networks let you create your own rules for response headers. That's handy if you don't have access to the server.
- Hosting and website builders: Some providers have a field for custom headers in their customer area. If it's missing, ask their support.
- CMS plugins: For WordPress, there are extensions for this. The web server is usually the better place, though, because the headers then also apply to images and files.
Set each header in one place only. If both the server and the CDN send a CSP, both apply at the same time, which quickly leads to blocked content.
Checking security headers
Your terminal is the quickest way:
curl -I https://example.comThe response lists all headers of the homepage. Without a terminal, open your browser's developer tools (F12), go to "Network", reload and click the first document. The same information appears under "Response headers". Mozilla also offers the HTTP Observatory on MDN, which rates your headers and suggests improvements. You'll find more checks in our article Check website security.
Common mistakes
- A long HSTS duration straight away: With includeSubDomains, a subdomain without a valid certificate is blocked for visitors until max-age expires.
- preload without a plan: The domain stays stuck on the list for months.
- Enforcing CSP immediately: Forms, maps or the cookie banner stop working.
'unsafe-inline'for scripts: This makes CSP lose much of its XSS protection.- Headers only on the homepage: Also check subpages, error pages and redirects.
- Duplicate headers: Server and CDN set the same rule differently.
Headers barely affect loading speed. If you are working on your server configuration anyway, take a look at our article Improve website speed.
Summary
With X-Content-Type-Options, Referrer-Policy and Permissions-Policy, you can make your website more secure in a few minutes. HSTS and Content-Security-Policy need more care: test first, then tighten gradually. You'll find more about encryption and server settings on our Headers & Encryption topic page.
Sources: MDN Web Docs, articles on Strict-Transport-Security, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy and X-XSS-Protection; hstspreload.org, notes on preload and rollout; OWASP Secure Headers Project; OWASP Top 10:2025.