
Missing HTTP Security Headers
Your server isn't sending the HTTP headers that tell browsers how to protect your visitors. Learn which headers to add and how.
What is this?
Every response your server sends to a browser can include a set of HTTP headers. A handful of those headers exist specifically to tell the browser how to protect the visitor: Strict-Transport-Security forces future visits to use HTTPS, Content-Security-Policy restricts which scripts can run, X-Frame-Options blocks your site from being loaded inside someone else's iframe, X-Content-Type-Options stops browsers from guessing file types, Referrer-Policy controls what information leaks when visitors click links to other sites, and Permissions-Policy decides which browser features (camera, microphone, geolocation) your site can use. Most WordPress hosts ship with none of these set.
Why does it matter?
Without these headers the browser uses its defaults, which are permissive for backwards compatibility. That means your visitors don't get the clickjacking protection, the MIME-sniffing protection, or the automatic HTTPS upgrade that modern browsers are capable of providing. None of the headers fix a vulnerability on your server — they're instructions to the browser. But they close off a long list of attack techniques that would otherwise work on a default WordPress install.
How to fix it
These steps are written for shared hosting (cPanel, Plesk, or similar). If you have direct server access, see the SSH section below.
Log in to cPanel and open File Manager.
Open your site's .htaccess file (in public_html). Create it if it doesn't exist.
Paste the following block at the top of the file:
<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 X-Frame-Options "SAMEORIGIN" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()" Header always set Content-Security-Policy "upgrade-insecure-requests" </IfModule>
Note: The Content-Security-Policy above is intentionally minimal. A stricter policy (e.g. limiting script sources) is more secure but needs per-site tuning because WordPress plugins often inject inline scripts. Start here and tighten later.
Save the file and reload your site.
For developers / SSH access
Apache users: the .htaccess snippet above works. For server-wide config, open your VirtualHost or site config (e.g. /etc/apache2/sites-available/yoursite.conf).
Nginx users: open your site's server block (e.g. /etc/nginx/sites-available/yoursite). Add inside the server { … } block:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always; add_header Content-Security-Policy "upgrade-insecure-requests" always;
Test the nginx config and reload:
sudo nginx -t && sudo systemctl reload nginx
How to verify the fix
Re-run your GuardingWP scan — the security_headers finding should pass. For a second opinion, check your site at securityheaders.com; it'll rate your header setup A through F and highlight anything still missing.
Re-run your scan to confirm this is resolved →Related issues
HTTP to HTTPS Redirect Missing
Visitors who type your address without 'https://' load the site over plain HTTP. Learn how to force every visitor onto the encrypted version.
Server Version in HTTP Headers
Your web server is announcing its software and version number. Learn how to suppress it.
PHP Version Exposed
Your server is broadcasting which version of PHP it runs. Learn how to hide it in a few steps.
Prefer to have this handled for you? Get this fixed — Simple ($49) →