HTTP security headers are among the cheapest, highest-value defenses a blog can deploy. They’re server-side response headers that instruct browsers how to handle a site’s content, and properly configured, they block entire categories of attack like cross-site scripting, clickjacking, and protocol downgrade attempts, all without touching a single line of application code. Despite this, surveys of the top million websites consistently show that fewer than half send a Content-Security-Policy at all, and many that do ship one so loose it offers little real protection.
Content-Security-Policy (CSP)
CSP is widely considered the most powerful security header available, and also the one most often misconfigured. It tells the browser exactly which sources are permitted to load scripts, styles, images, fonts, and frames on a page, effectively shutting down the browser-side execution path that most XSS attacks rely on.
The modern best-practice approach for 2026 uses nonce-based CSP with strict-dynamic, meaning every script included in the HTML carries a nonce attribute that matches a random value emitted in the CSP header itself. A common and serious misconfiguration is including unsafe-inline in the policy, which allows execution of any inline script, including ones an attacker manages to inject, effectively defeating the entire purpose of setting CSP in the first place.
Rolling it out safely:
- Start in report-only mode using the
Content-Security-Policy-Report-Only header for 2 to 4 weeks
- Monitor violation reports without actually blocking anything during this window
- Fix any legitimate violations that surface
- Switch to full enforcement only once the policy is clean
Strict-Transport-Security (HSTS)
HSTS tells browsers to only ever connect to your domain over HTTPS, and to remember that instruction for a set period of time. Once a browser has seen a valid HSTS header from your site, it will refuse to make plain HTTP connections to that domain for the duration specified, which closes off SSL-stripping attacks that rely on intercepting that first unencrypted request.
A phased rollout is recommended:
- Begin with a short
max-age (around 300 seconds) while verifying nothing breaks
- Raise
max-age to a full year (31536000 seconds) and add includeSubDomains
- Only add the
preload directive once you’re confident every subdomain permanently serves HTTPS — submitting to the preload list is a long-term commitment, since removal afterward can take months
A common mistake is enabling includeSubDomains when an internal tool on a subdomain isn’t configured for HTTPS — once a browser has seen the HSTS header, it will simply refuse to connect to that subdomain over HTTP going forward.
X-Content-Type-Options
This header prevents MIME-type sniffing, where a browser tries to guess a file’s type rather than trusting what the server declares. Left unset, this guessing behavior can be exploited to trick browsers into executing content as something other than what it actually is. Setting X-Content-Type-Options: nosniff closes this off and requires no application changes.
Clickjacking Protection: X-Frame-Options and frame-ancestors
X-Frame-Options is the legacy header for preventing a page from being loaded inside a malicious iframe on another site. Its modern replacement is the CSP directive frame-ancestors, which is more flexible since it supports a list of allowed origins rather than an all-or-nothing setting. Because older browsers may not support the CSP version, best practice is to send both together — frame-ancestors for modern browsers, with X-Frame-Options: DENY included as a fallback for anything older.
Permissions-Policy
This header controls which browser features and APIs, like camera, microphone, or geolocation access, a page and any embedded content are allowed to use. It’s a relatively easy header to add and meaningfully reduces the attack surface for any blog handling even moderately sensitive visitor data, though it ranks as lower priority than CSP and HSTS.
Cross-Origin Isolation Headers
For blogs or web apps that need high-resolution timers or SharedArrayBuffer support, three headers work together to enable cross-origin isolation and add protection against Spectre-style side-channel attacks:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
These headers can break functionality on sites that embed third-party content like iframes, images, or fonts, unless those external resources explicitly opt in with their own Cross-Origin-Resource-Policy: cross-origin header. For blogs that don’t rely on these advanced browser features, this set is optional — it’s worth implementing the other headers first and adding these only if a specific feature genuinely requires them.
Headers Worth Skipping or Retiring
Not every legacy header still pulls its weight. X-XSS-Protection controlled an old browser-based XSS filter that modern browsers no longer rely on, and keeping it enabled can occasionally introduce its own bugs rather than preventing anything. Deliberately setting it to disabled is now considered part of a modern baseline, alongside actively maintained headers like CSP and HSTS.
It’s also worth cleaning up headers that inadvertently leak information, such as X-Powered-By, which can announce your exact server or language version to anyone probing the site, effectively handing attackers free reconnaissance.
Where to Focus First
For a blog without extensive application-level access to tinker with (as is common on shared hosting or managed platforms), the highest-value headers achievable without code changes are HSTS for TLS enforcement, X-Content-Type-Options for MIME-sniffing prevention, and either X-Frame-Options or CSP’s frame-ancestors for clickjacking prevention. These three alone mitigate some of the most common real-world attack classes and can typically be added directly through server configuration.
Checking Your Work
Once headers are in place, tools like the Mozilla Observatory (now part of MDN) or securityheaders.com can scan a domain and return a letter grade alongside a specific list of what’s missing or misconfigured. An HTTP headers checker is also useful for spotting duplicate headers, since sending two separate CSP headers means only their intersection gets enforced, which can produce confusing, unintended results.
Join The Discussion
Security headers are one of those blog maintenance tasks that’s easy to overlook until something goes wrong, even though most of them take just a few lines of server configuration to set up. Have you run your own blog through a header security scanner, and did anything surprising turn up? Share your experiences, questions, or configuration tips below, especially if you’ve found a setup that works well for a specific hosting platform.