...
Contact Us Contact Us

How to Check HTTP Security Headers and Fix the Six That Matter

How to Check HTTP Security Headers and Fix the Six That Matter How to Check HTTP Security Headers and Fix the Six That Matter

Every time a browser requests a page, the server answers with a status code and a block of HTTP response headers before any HTML arrives. Those headers tell the browser how long to cache the page, whether it may be embedded in an iframe, whether to guess file types, and whether to insist on HTTPS. Most of them are invisible to visitors, which is why so many production sites ship without the handful that protect users from clickjacking, downgrade attacks and injected scripts.

This article shows you how to read a response, which six headers are worth adding to almost every site, and the configuration to add them on the platforms you are most likely to be running.

How to see a site’s response headers

You have three options:

Advertisement

  • Browser DevTools. Open the Network tab, reload, click the first document request and read the Response Headers panel. Accurate, but you only see your own browser’s view and it is slow for checking several sites.
  • cURL. curl -I https://example.com prints the headers of a HEAD request. Some servers answer HEAD and GET differently, so curl -sD - -o /dev/null https://example.com is more reliable.
  • An online checker. The HTTP Header Checker fetches the URL from a neutral location, shows the status code, lists every header, and flags which of the six security headers below are missing. It is the fastest way to audit a client site or compare before-and-after when you change server config.

Reading a typical response

HTTP/2 200
content-type: text/html; charset=UTF-8
cache-control: max-age=0, no-cache, no-store, must-revalidate
content-encoding: br
server: nginx
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN

The first line is the protocol and status. content-type and content-encoding describe the body. cache-control governs caching by browsers and CDNs. Everything from strict-transport-security down is a security header, and that is the group most sites are missing.

The six security headers to add

1. Strict-Transport-Security (HSTS)

Tells the browser to use HTTPS for this domain for the next n seconds, even if the user types http://. It closes the window where a redirect from HTTP to HTTPS can be intercepted.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Start with a short max-age (a day) while you confirm every subdomain works over HTTPS, then raise it to a year. Only add preload if you intend to submit the domain to the browser preload list; it is very hard to undo.

2. Content-Security-Policy (CSP)

Restricts where scripts, styles, images and frames may load from. It is the single most effective defence against cross-site scripting, and also the header most likely to break something if set carelessly. A safe way to begin is report-only mode:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://www.googletagmanager.com; report-uri /csp-report

Watch the reports for a week, add the sources you actually use, then switch the header name to Content-Security-Policy. If a full policy is more than you want to maintain, at minimum send Content-Security-Policy: upgrade-insecure-requests; frame-ancestors 'self', which fixes mixed content and clickjacking without touching scripts.

3. X-Frame-Options

Prevents your pages from being loaded inside an iframe on another domain, which is how clickjacking works. frame-ancestors in CSP supersedes it, but older browsers still read this one, so send both.

X-Frame-Options: SAMEORIGIN

4. X-Content-Type-Options

Stops browsers from “sniffing” a response and executing it as a different type than the server declared. One value, no downside:

X-Content-Type-Options: nosniff

5. Referrer-Policy

Controls how much of the current URL is sent in the Referer header when a user clicks an outbound link. The default in modern browsers is already reasonable, but setting it explicitly avoids leaking query strings to third parties:

Referrer-Policy: strict-origin-when-cross-origin

6. Permissions-Policy

Disables browser features your site does not use, so an injected script cannot silently request the camera, microphone or location:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

Where to add them

Apache (.htaccess)

<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
  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 Content-Security-Policy "upgrade-insecure-requests; frame-ancestors 'self'"
</IfModule>

Nginx

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;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "upgrade-insecure-requests; frame-ancestors 'self'" always;

The always flag matters: without it Nginx omits the headers on error responses.

WordPress without server access

On managed hosting where you cannot edit the server config, a small snippet in a code-snippets plugin or your child theme’s functions.php does the same job:

add_action( 'send_headers', function () {
    header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains' );
    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=()' );
} );

Note that a page cache or CDN in front of WordPress may serve its own headers; check the live result rather than assuming the PHP ran.

Cloudflare

Rules → Transform Rules → Modify Response Header lets you add static headers at the edge with no code, and they apply even when the origin is cached. This is the quickest route if the site already sits behind Cloudflare.

Verify the change

Deploy, purge any cache, then run the URL through the HTTP Header Checker again. The six checks should now show green. While you are there, look at the rest of the response: a server header that includes a version number (Apache/2.4.41) is worth suppressing, and a missing content-encoding on an HTML response means compression is off, which is a performance fix you can make in the same session.

If you maintain several sites, keep a note of the header set you standardise on and re-check after every hosting migration. Security headers are one of the first things lost when a site moves servers, because they live in config rather than in the site itself.

Frequently asked questions

Will these headers slow the site down?

No. They add a few hundred bytes to each response and require no extra processing.

I added HSTS and now a subdomain won’t load. What happened?

includeSubDomains forces HTTPS on every subdomain. One of them is probably HTTP-only. Fix its certificate, or remove the directive until you have.

Is X-XSS-Protection still needed?

No. Modern browsers have removed the XSS auditor it controlled, and Content-Security-Policy replaces it. Some scanners still flag its absence; ignore them.

Can I check headers for a site I don’t own?

Yes. Response headers are public; any HTTP client sees them. Checking a competitor’s or a prospective client’s headers is normal practice.

Try it now: HTTP Header Checker

Free, runs in your browser, nothing uploaded, no sign-up.

Open the tool →
Add a comment Add a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Submit Comment

Advertisement
Seraphinite AcceleratorOptimized by Seraphinite Accelerator
Turns on site high speed to be attractive for people and search engines.