1 Introduction
Every time your website answers a browser, it sends the page and a set of headers: short instructions the visitor never sees. A few of them are pure security switches. They tell the browser "only ever talk to me over HTTPS", "never run scripts from anywhere else", or "do not let another site frame me". The browser already knows how to enforce all of this; it just waits for you to ask.
Missing headers rarely break into a site on their own. What they do is remove a safety net, so that a single bug elsewhere (an injected script, a link to http://, a page loaded inside an attacker's frame) turns into a working attack. That is why a domain scan lists them: they are cheap to add and they make whole classes of attacks harder.
1 line
Most headers are one line in your web server, reverse proxy or CDN settings
1 year
HSTS max-age required to join the browser preload list (31,536,000 s)
0
Protection left in X-XSS-Protection: modern browsers ignore it, CSP replaced it
2 How It Works
A scanner does what a browser does: it requests your homepage and reads the response headers. Here is what a well-configured answer looks like:
HTTP/2 200
strict-transport-security: max-age=31536000; includeSubDomains
content-security-policy: default-src 'self'; frame-ancestors 'none'; object-src 'none'
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=()
set-cookie: session=...; Secure; HttpOnly; SameSite=Lax
Strict-Transport-Security (HSTS)
After the first visit, the browser refuses plain HTTP for your domain for max-age seconds. It stops attackers on a café Wi-Fi from downgrading the connection and reading or changing traffic.
Content-Security-Policy (CSP)
An allow-list of where scripts, styles, images and frames may come from. If an attacker injects a <script> (XSS), the browser refuses to run it. The most powerful header, and the one that needs the most care.
X-Frame-Options / frame-ancestors
Decides who may display your pages inside a frame. Without it, a malicious page can load your site invisibly and trick users into clicking your buttons (clickjacking). frame-ancestors in CSP is the modern form; X-Frame-Options: DENY still covers old browsers.
X-Content-Type-Options: nosniff
Stops the browser from guessing a file's type. Without it, an uploaded "image" containing JavaScript may be executed as a script.
Referrer-Policy
Controls how much of the current URL is sent to other sites when a visitor clicks a link. Prevents tokens or internal paths in URLs from leaking to third parties.
Permissions-Policy
Switches off browser features your site does not use (camera, microphone, location), so an injected script or an embedded third party cannot ask for them.
3 Detailed Analysis
Missing versus weak
A scan reports two kinds of problems. A missing header is easy to read. A weak one is present but configured so that it protects little:
HSTS with a short max-age
A max-age of a few minutes expires before the next visit. Aim for six months to a year once HTTPS works everywhere.
CSP with 'unsafe-inline', 'unsafe-eval' or *
These re-allow exactly what CSP is meant to block: inline scripts, string evaluation, any origin. A policy containing them looks good on a checklist and stops very little XSS. Replace inline scripts with files, or use nonces.
CSP only in Report-Only mode
Content-Security-Policy-Report-Only reports violations without blocking anything. Fine for testing, no protection in production.
Version disclosure
Server: nginx/1.18.0 or X-Powered-By: PHP/7.4 tell an attacker which known vulnerabilities to try. Hiding versions is not a fix, but there is no reason to advertise them.
A safe starting configuration (nginx)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; frame-ancestors 'none'; object-src 'none'" always;
server_tokens off;
Behind a CDN (Cloudflare, Fastly, CloudFront), the same headers are set in its response-header rules, with no change to your servers. Apache, Caddy and IIS have direct equivalents.
Rolling out the two risky ones
CSP: start in Report-Only, open your site and watch the browser console for violations, adjust the allow-list (analytics, fonts, payment widgets), then switch the header name to Content-Security-Policy.
HSTS: start with a short max-age (one day), check every subdomain answers over HTTPS before adding includeSubDomains, then raise it. Add preload only when you are sure: leaving the preload list takes months.
Check your headers on mlab.sh
A domain scan reads the security headers and cookie flags your site returns, and flags those that are missing or too weak to protect.
Scan your domain on mlab.sh4 Red Flags
No HSTS on a site with a login
Anyone on the same network can strip HTTPS on the first request and capture credentials. Login, admin and payment pages need HSTS first.
Session cookie without HttpOnly or Secure
A single XSS can read the session and hand the account to the attacker, and a single HTTP request can leak it on the network.
A CSP that allows everything
script-src * 'unsafe-inline' 'unsafe-eval' is a CSP in name only. Treat it as missing.
Pages that can be framed by anyone
Without frame-ancestors or X-Frame-Options, account settings or payment confirmation pages are exposed to clickjacking.
Exact software versions in headers
An outdated version number in Server or X-Powered-By is an invitation. Hide it, and above all update the software.
Related Modules
SPF, DKIM and DMARC for your domain
Stop attackers from sending email as your domain: what SPF, DKIM and DMARC do, how to read a scan result and how to reach p=reject safely.
Subdomain takeover and dangling DNS
How a forgotten CNAME or NS record lets anyone serve content on your subdomain, and how to find and clean up dangling DNS before an attacker does.
Recognizing a phishing link
Techniques for detecting fraudulent URLs that mimic legitimate websites.
Source: mlab Academy — Cybersecurity Awareness Platform
URL: https://academy.mlab.sh//page/http-security-headers
Module: HTTP security headers explained — Secure your domain
Disclaimer: This content is for awareness purposes only.