You ran your website through a security scanner and it came back with a list of “missing security headers”: Content-Security-Policy, Strict-Transport-Security, X-Frame-Options and a few more. The report gave you a poor grade, but it did not explain what any of them do, or whether adding them could break something.
Security headers are short instructions your server sends to the visitor’s browser along with each page. They tell the browser to be stricter about certain things. They do not fix a hacked site or replace updates, but a few of them close off whole kinds of attack cheaply. Here is what the main ones mean in plain language, and how to add them without trouble.
What a header actually is
Every time a browser asks for a page, the server replies with the page itself plus a block of extra lines called headers. Some are routine, like the type of file being sent. Security headers are ones that change how the browser behaves: “only ever connect to me over HTTPS”, “do not let other sites show me in a frame”, “only run scripts from these places”.
The browser enforces them, not your server. That is why they help: even if something odd ends up on a page, the browser can refuse to act on it.
You can see your own headers. In Chrome, Edge or Firefox, open the developer tools, go to the Network tab, reload the page, click the first entry and look under Response Headers.
The headers worth knowing
Strict-Transport-Security (HSTS)
This tells the browser: for a set period, only connect to this site over HTTPS, even if someone types or clicks a plain http:// link. It protects visitors on untrusted networks, such as public Wi-Fi, from being quietly kept on an unencrypted connection.
The setting that matters is max-age, how long the browser remembers the rule, in seconds. Start with a short value, and only raise it once you are certain every part of your site works on HTTPS. Be careful with includeSubDomains, which applies the rule to every subdomain too, and with preload, which asks browsers to build your site into their own lists. Preload is hard to undo, so leave it alone unless you are confident. If your site still has insecure parts, fix those first; our guide to mixed content warnings covers that.
Content-Security-Policy (CSP)
The most powerful header and the one most likely to break things. It lists where the page is allowed to load scripts, styles, images, fonts and frames from. If an attacker manages to inject a script that loads from their own domain, a good policy stops the browser running it. That makes it a strong defence against cross-site scripting, which is explained in our post on SQL injection and XSS.
The difficulty is that a typical WordPress site loads code from many places: analytics, a chat widget, fonts, a payment gateway, embedded videos, a cookie banner. Miss one and that feature quietly stops working. The safe approach is to start with Content-Security-Policy-Report-Only. The browser then reports what it would have blocked, in the developer console, without blocking anything. Use the site for a while, add each legitimate source, and only switch to the enforcing header once the reports are clean.
X-Content-Type-Options
The only sensible value is nosniff. It tells the browser to trust the file type the server declares rather than guessing. Without it, a browser might treat an uploaded file as a script. It is safe to add to almost every site.
X-Frame-Options and frame-ancestors
These stop other websites showing your pages inside a frame. That blocks “clickjacking”, where your real page is loaded invisibly under a fake one so a visitor clicks your buttons without knowing. X-Frame-Options: SAMEORIGIN allows framing only by your own site. The newer way to say the same thing is the frame-ancestors part of a Content-Security-Policy. Check first whether anything legitimate embeds your pages, such as a booking widget on a partner site.
Referrer-Policy
When a visitor clicks a link from your site to another site, the browser may tell that site which page they came from. Referrer-Policy controls how much is shared. strict-origin-when-cross-origin sends only your domain, not the full page address, to other sites, and nothing when moving from HTTPS to HTTP. This matters if your page addresses ever contain anything private, like an order or search term.
Permissions-Policy
This lets you switch off browser features your site never uses, such as the camera, microphone or location, so that no script on the page can ask for them. For most business sites a short policy that disables those three is harmless.
One header to drop rather than add
Older guides recommend X-XSS-Protection. It controlled a filter that modern browsers have removed, and the filter itself could cause problems. Do not add it. If a scanner still asks for it, that scanner is out of date.
How to add them on a WordPress site
There are three common places, and you only need one.
- At the server. On Apache hosting, headers can be set in the
.htaccessfile withHeader setlines, if the host has the headers module enabled. On Nginx they go in the server configuration withadd_header. This is the cleanest option but needs care: a typo in.htaccesscan take the whole site down, so keep a copy of the original. - At a CDN or firewall. If your site sits behind a service like Cloudflare, you can add response headers in its dashboard without touching the server. Our post on website firewalls explains how that layer works.
- With a plugin. Several security plugins can add headers for you. This is easiest, but check that you are not also setting them at the server, because duplicate or conflicting headers cause confusing results.
A safe order to add them
- X-Content-Type-Options: nosniff.
- Referrer-Policy: strict-origin-when-cross-origin.
- X-Frame-Options: SAMEORIGIN, after checking nothing legitimate frames your site.
- Permissions-Policy, disabling features you do not use.
- Strict-Transport-Security with a short max-age, raised later.
- Content-Security-Policy in Report-Only mode, then enforced once the reports are clean.
After each change, test the things that earn you money: the contact form, checkout and payment, login, and any embedded maps or videos. Test in a private window so cached pages do not fool you.
For the exact syntax of any header, Mozilla’s reference on HTTP headers is reliable and written clearly.
Keep the grade in perspective
A perfect score on a header scanner does not mean a site is secure, and a poor one does not mean it is about to be hacked. Headers are a useful extra layer. Out-of-date plugins, weak passwords and missing backups are more often behind real trouble. If you would like the headers set up properly alongside the bigger items, that is part of our website security maintenance work, with forms and checkout tested after each change.
Next in this series: Changing the WordPress Login URL: Does It Help?