Security headers are one of those topics that sound technical and obscure but actually matter quite a bit. They are pieces of information that your server sends to browsers along with every page. The information tells browsers how to handle your content in ways that improve security.
Most sites have inadequate security headers because nobody set them up. The defaults that web servers send are often missing important headers entirely. Adding them is usually straightforward and significantly improves security against several common attacks.
This piece covers what security headers are, which ones matter, and how to configure them on your site.
What Security Headers Actually Are
HTTP headers are metadata sent with web responses. Security-related headers tell browsers about security policies and behaviors.
How Headers Work
When a browser requests a page from your site, the server responds with the page content plus headers. The headers include things like the content type, caching directives, and security policies.
The browser reads the headers and behaves accordingly. Headers can tell the browser to enforce HTTPS, block certain content, or restrict what scripts can run.
Why Headers Matter for Security
Several common web attacks can be mitigated through proper headers. Cross-site scripting. Clickjacking. Content type sniffing exploits. Mixed content issues. Information leakage.
Each of these has a header that helps prevent it. Sites without the headers remain vulnerable. Sites with proper headers add meaningful defense.
How to Check Your Current Headers
Several tools show what headers your site currently sends:
Mozilla Observatory (observatory.mozilla.org) gives a comprehensive security grade based on headers.
Security Headers (securityheaders.com) provides a simple grade and explanation.
Browser developer tools show all headers on the Network tab.
Running these scans reveals what your site is doing today and what needs improvement.
The Important Security Headers
Several headers matter for most sites.
Strict-Transport-Security (HSTS)
HSTS tells browsers to always use HTTPS for your site, even if the user typed HTTP. Once the browser sees the HSTS header, it remembers and refuses to make HTTP connections to your site.
This protects against attacks that try to downgrade connections to HTTP and intercept traffic.
The basic header looks like:
Strict-Transport-Security: max-age=31536000; includeSubDomains
The max-age value is how long the browser should enforce HTTPS, in seconds. 31536000 is one year.
Be careful with this header. Once set, browsers enforce HTTPS for the specified duration even if you want to switch back to HTTP. Make sure your HTTPS is solid before enabling HSTS.
X-Frame-Options
This header controls whether your site can be embedded in iframes on other sites. Without it, attackers can create pages that embed your site and trick users into clicking on the embedded content (clickjacking).
The simple value:
X-Frame-Options: SAMEORIGIN
This allows iframes only from the same domain. For sites that never need to be embedded anywhere, use DENY instead.
X-Content-Type-Options
This header prevents browsers from guessing content types. Without it, browsers sometimes interpret files as types other than what the server specified, which can lead to security issues.
The header value:
X-Content-Type-Options: nosniff
There is only one valid value and you want it on every site.
Content-Security-Policy
CSP is the most powerful security header. It controls what sources of content the browser is allowed to load. Scripts, styles, images, fonts, frames, all can be restricted.
A properly configured CSP prevents most cross-site scripting attacks because injected scripts will not match the allowed sources.
The next piece in this series covers CSP in detail. It is involved enough to deserve its own discussion.
Referrer-Policy
This header controls what information gets sent in the Referer header when users click links from your site. By default, browsers send the full URL of the source page, which can leak sensitive information.
A reasonable default:
Referrer-Policy: strict-origin-when-cross-origin
This sends the full URL for same-origin requests, just the origin for cross-origin requests, and nothing for HTTPS to HTTP transitions.
Permissions-Policy
The newer name for what used to be Feature-Policy. Controls which browser features can be used on your site. Camera, microphone, geolocation, and others.
For most sites, restricting features they do not use adds defense in depth:
Permissions-Policy: camera=(), microphone=(), geolocation=()
This denies the listed features entirely. Sites that need them can specify allowed origins.
X-XSS-Protection
This header controlled the XSS filter in older browsers. Modern browsers have removed the filter, so this header is less important than it once was.
For compatibility with older browsers, you can still set it:
X-XSS-Protection: 1; mode=block
But CSP is the better defense against XSS in modern browsers.
How to Set Security Headers
The implementation depends on your hosting setup.
Apache (.htaccess)
For Apache servers, add headers in the .htaccess file:
Header set Strict-Transport-Security “max-age=31536000; includeSubDomains” Header set X-Frame-Options “SAMEORIGIN” Header set X-Content-Type-Options “nosniff” Header set Referrer-Policy “strict-origin-when-cross-origin”
The Header directive requires mod_headers to be enabled. Most Apache setups have it enabled by default.
Nginx
For Nginx, add headers in the server configuration:
add_header Strict-Transport-Security “max-age=31536000; includeSubDomains” always; add_header X-Frame-Options “SAMEORIGIN” always; add_header X-Content-Type-Options “nosniff” always; add_header Referrer-Policy “strict-origin-when-cross-origin” always;
The “always” parameter ensures the headers get sent even for error responses.
WordPress Plugins
For WordPress users without server access, plugins handle headers. Several options:
Sucuri Security includes header configuration.
Headers Security Advanced & HSTS WP focuses specifically on security headers.
Really Simple SSL has security header options in premium versions.
The plugin approach is easier but less efficient than server-level configuration.
Cloudflare Headers
If you use Cloudflare, you can add headers through Cloudflare’s interface. This works regardless of your origin server configuration.
Cloudflare Page Rules and Transform Rules both support adding headers.
Hosting Control Panels
Some hosts let you configure headers through their control panel. Check your hosting documentation.
Testing Your Headers
After configuring headers, test them.
Online Scanners
Mozilla Observatory and Security Headers provide automated scans. They show what headers you have, what is missing, and grade the configuration.
Run these scans before and after making changes to see improvement.
Browser Developer Tools
Browser dev tools show every header sent for any page. Open the Network tab, refresh the page, and look at the response headers.
Curl Command Line
For technical users, the curl command shows headers directly:
curl -I https://yoursite.com
The -I flag shows just headers, not page content.
Common Header Configuration Mistakes
People stumble in predictable ways.
Enabling HSTS Without HTTPS Being Solid
HSTS forces browsers to use HTTPS. If your HTTPS has problems, users cannot access your site.
Test HTTPS thoroughly before enabling HSTS. Start with a short max-age (like 300 seconds) and increase gradually as you verify everything works.
Missing Headers on Some Responses
Headers should be set for all responses, not just successful ones. The “always” parameter in Nginx and equivalent settings in other servers ensure consistent header application.
Conflicting Headers
If multiple systems set the same header, the results can be unpredictable. Check that you do not have Cloudflare setting one value while your origin server sets another.
Too Permissive CSP
The CSP needs to allow what your site legitimately needs. Too restrictive and the site breaks. Too permissive and the protection is minimal.
CSP requires careful configuration. The next piece covers this.
Forgetting Subdomains
If your main site has good headers but subdomains do not, attacks can target the subdomains. Apply consistent header policies across all subdomains.
Not Testing After Changes
Header changes can break things in unexpected ways. After every change, test to confirm the site still works correctly.
When Header Configuration Goes Wrong
Sometimes header changes break things.
Mixed Content Issues
After enabling HSTS, mixed content (HTTP resources on HTTPS pages) gets blocked completely instead of just generating warnings. Audit your site for mixed content before enabling HSTS.
Frame Embedding Blocks
X-Frame-Options can break legitimate uses where your content needs to be embedded elsewhere (like in a partner’s site or a customer service tool).
If your site needs to be embedded somewhere specific, use X-Frame-Options: ALLOW-FROM (older browsers) or Content-Security-Policy: frame-ancestors (newer browsers) to allow specific origins.
CSP Breaking Functionality
CSP restrictions can break scripts, styles, or other resources your site uses. Start with a permissive CSP and tighten gradually. Or use CSP in report-only mode initially to see what would be blocked without actually blocking it.
Site Inaccessible After HSTS
If something goes wrong with HTTPS after HSTS is set, users cannot access the site even via HTTP. Fix the HTTPS issue. Browsers will return when HTTPS works again.
For testing or temporary HSTS removal, browsers have ways to clear HSTS for specific sites, but this is not something users can easily do.
Bringing the Headers Picture Together
Security headers are a small but meaningful improvement to site security. The configuration is mostly straightforward. The protection against several attack types is real.
For most sites, the right approach is to set the core security headers consistently. HSTS for HTTPS enforcement. X-Frame-Options for clickjacking protection. X-Content-Type-Options for content sniffing protection. Referrer-Policy for information disclosure protection. Permissions-Policy for feature restriction. Content-Security-Policy for XSS and data injection protection.
The setup is one-time work. The protection persists. Each header addresses specific attacks that would otherwise have to be defended against through other means or accepted as risk.
Sites with proper security headers do not eliminate all attacks but they do raise the bar significantly. Attacks that would have succeeded without the headers now fail. The blast radius of attacks that do succeed gets limited.
If your site has not been audited for security headers, this is worth doing soon. Run Mozilla Observatory or Security Headers on your site. See what is missing. Add the headers either through server configuration or plugins. Re-scan to confirm. The work is bounded. The improvement is concrete.
For sites that take security seriously, security headers are part of the baseline configuration. The absence of proper headers is a security issue worth addressing. The presence of proper headers is one of the markers of a site that has been thoughtfully configured. Sites move from low security grades to high security grades primarily through proper header configuration. The improvement does not require new infrastructure or major investments. It just requires the small amount of attention to apply known best practices to your site.