Most WordPress security guides focus on login protection, firewalls, and keeping plugins up to date. Those things matter, but there is another layer of protection that often gets overlooked: HTTP security headers. These are instructions your web server sends to the browser along with every page request, telling it how to handle your site’s content.
Without them, browsers make their own decisions — and those defaults leave your site open to a range of common attacks. Adding security headers closes those gaps with a few lines of server configuration or PHP. No plugin required, no ongoing maintenance, and no impact on page speed.
If you have already worked through the basics of how to secure a WordPress website and have SSL running, security headers are the logical next step. They take about ten minutes to set up and will immediately improve how your site scores on security scanning tools.
Quick Answer
You add HTTP security headers to WordPress either through your .htaccess file (on Apache servers) or through a add_action( 'send_headers' ) hook in your functions.php file. The most important headers to add are X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and Strict-Transport-Security (HSTS). A Content Security Policy (CSP) is also worth adding, but requires more careful configuration.
Why HTTP Security Headers Matter
Security headers protect against a specific class of browser-based attacks. They are not a replacement for a firewall or login hardening — they work at a different level. Where a WordPress firewall blocks malicious requests before they reach your site, security headers tell the browser what to do once a page has loaded.
Common threats they protect against include:
- Clickjacking — an attacker embeds your site in an invisible iframe and tricks users into clicking on hidden buttons
- MIME sniffing — the browser guesses a file’s content type and executes something it shouldn’t
- Cross-site scripting (XSS) — malicious scripts injected into your pages run in the visitor’s browser
- Insecure mixed content — HTTP resources loaded on an HTTPS page, weakening your SSL protection
- Data leakage — your site’s URL and referrer data sent to third-party sites unnecessarily
Tools like securityheaders.com grade your site on these headers. Most new WordPress sites score F or D until headers are explicitly added.
The Headers You Should Add
Here is what each header does and the recommended value for most WordPress sites.
X-Frame-Options
Prevents your site from being loaded inside an iframe on another domain. This blocks clickjacking attacks entirely.
X-Frame-Options: SAMEORIGIN
SAMEORIGIN allows iframes only from your own domain. Use DENY if you never need iframes at all.
X-Content-Type-Options
Stops the browser from guessing (sniffing) the content type of a file. Only one valid value exists for this header.
X-Content-Type-Options: nosniff
Referrer-Policy
Controls how much referrer information is sent when a visitor clicks a link to another site. By default, browsers send the full URL, which can leak private information or internal URL structures.
Referrer-Policy: strict-origin-when-cross-origin
This sends only your domain name (not the full page URL) when linking to external sites, while sending the full URL for same-origin requests.
Permissions-Policy
Controls which browser features your site is allowed to use — camera, microphone, geolocation, and so on. For most WordPress content sites, restricting these entirely makes sense.
Permissions-Policy: camera=(), microphone=(), geolocation=()
If you run WooCommerce or use features that need location access (like store finders), adjust accordingly.
Strict-Transport-Security (HSTS)
Tells browsers to always connect to your site over HTTPS, even if someone types http://. This only applies once you have a valid SSL certificate set up and working correctly — do not add HSTS before SSL is confirmed.
Strict-Transport-Security: max-age=31536000; includeSubDomains
max-age=31536000 is one year. Start with a shorter value (like 86400 for one day) if you want to test first, then increase it once you are confident SSL is stable.
Method 1: Add Headers via .htaccess (Apache)
If your site runs on Apache (most shared hosting and many managed WordPress hosts), you can add security headers directly to your .htaccess file. This is the most reliable method because the headers are sent at the server level before WordPress even loads.
Step 1. Connect to your server using FTP or your host’s file manager and open the .htaccess file in your WordPress root directory.
Step 2. Add the following block above the WordPress # BEGIN WordPress section:
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
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 Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>
Step 3. Save the file and reload your site. Run a check at securityheaders.com to confirm the headers are appearing.
The <IfModule mod_headers.c> wrapper ensures the block only runs if the Apache headers module is enabled — it will not cause errors if it is not available.
Method 2: Add Headers via functions.php
If you are on Nginx, or prefer to manage everything through WordPress, you can send security headers using the send_headers action hook in your theme’s functions.php file (or a site-specific plugin). This method works on any hosting stack.
Step 1. Open your child theme’s functions.php file. If you do not have a child theme, create one before editing — changes made to a parent theme’s functions.php are overwritten on theme updates.
Step 2. Add this function:
function veravix_security_headers() {
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'X-Content-Type-Options: nosniff' );
header( 'Referrer-Policy: strict-origin-when-cross-origin' );
header( 'Permissions-Policy: camera=(), microphone=(), geolocation=()' );
header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains' );
}
add_action( 'send_headers', 'veravix_security_headers' );
Step 3. Save and verify with securityheaders.com. The headers should now appear on every page WordPress serves.
Content Security Policy: Handle With Care
A Content Security Policy (CSP) is the most powerful security header available, but also the most complex. It controls which scripts, stylesheets, images, and other resources your site is allowed to load — and from where. A misconfigured CSP will break your site by blocking resources you actually need.
WordPress sites typically load resources from multiple sources: Google Fonts, analytics scripts, CDN assets, plugin-injected inline scripts, and third-party embeds. Writing a CSP that allows all of these without being too permissive takes time and testing.
For most sites, the safe approach is:
- Start with the five headers above — they provide most of the protection with minimal risk.
- Use your browser’s developer tools (Network tab) or a tool like MDN’s HTTP headers reference to understand what resources your site loads.
- Test a CSP in report-only mode using
Content-Security-Policy-Report-Onlybefore enforcing it.
A CSP is worth adding eventually, but getting the other five headers right first is the practical starting point.
Practical Tips
- Always test in a staging environment first if possible. A misconfigured header rarely breaks a site, but it is safer to verify before pushing changes to production.
- On LiteSpeed servers (common with LiteSpeed Cache), headers can also be set via the
.htaccessmethod — LiteSpeed supports Apache-compatible directives. - Some managed WordPress hosts (like WP Engine or Kinsta) set certain security headers at the server level already. Run a check before adding duplicates.
- If you use a CDN, check whether it strips or rewrites custom headers — some CDNs do, and you may need to configure headers at the CDN level instead.
Common Mistakes
- Adding HSTS before SSL is confirmed. If your HTTPS setup has any issues and HSTS is active, browsers will refuse to load your site at all. Always verify SSL is stable first.
- Setting X-Frame-Options to DENY unnecessarily. If any part of your site uses iframes — including some payment gateways and embedding tools — DENY will break them. SAMEORIGIN is the safer default.
- Duplicating headers. If your host already sends a header and you add the same one, browsers may receive conflicting values. Check existing headers before adding your own.
- Forgetting to test after adding headers. Always verify with securityheaders.com after any change. Headers that look correct in the config can still fail to appear if a module is disabled.
When to Use a Plugin Instead
If you are not comfortable editing .htaccess or functions.php, a security plugin like Wordfence or Solid Security can apply some of these headers through the dashboard. The coverage varies by plugin — not all of them implement every header — so always verify with a scanner after setup.
For sites where you have server access and are confident with basic file editing, doing it manually gives you more control and avoids adding a plugin dependency for something that is straightforward to implement directly.
Conclusion
Run your site through securityheaders.com now. If you see anything below a B grade, add the five headers above using whichever method matches your hosting setup. It takes ten minutes and closes a set of vulnerabilities that most WordPress sites leave open by default.

Etienne Basson works with website systems, SEO-driven site architecture, and technical implementation. He writes practical guides on building, structuring, and optimizing websites for long-term growth.