A missing security header rarely takes more than one line to fix. Finding out which ones are missing, and understanding what each one actually protects against, is the part most sites skip. Here's what each header does, what its absence actually exposes, and how to fix it.

Content-Security-Policy (CSP): the header that stops XSS from mattering

CSP tells the browser which sources are allowed to load scripts, styles, images, and frames on your page. Without it, any script that gets injected into your site, through a vulnerable dependency, an unsanitized form field, a compromised third-party widget, executes with full trust and full access to cookies, local storage, and the DOM. CSP doesn't prevent the injection itself. It prevents the injected script from running, which is what actually stops cross-site scripting (XSS) from turning into a real compromise.

A solid starting policy restricts every resource type to your own domain by default, explicitly allows scripts only from origins you trust, and blocks plugin-based content entirely. The most common mistake isn't a missing CSP, it's a CSP that allows inline scripts or dynamic code evaluation, which defeats most of the protection by letting injected scripts run anyway. If your site depends on inline scripts, use a nonce or hash-based approach instead of a blanket allowance. Most teams start by deploying the policy in report-only mode to see what would break before enforcing it in production.

Strict-Transport-Security (HSTS): closing the downgrade window

HTTPS alone doesn't protect the first request. Without HSTS, a browser's very first connection to your domain can still be made over plain HTTP, and that opens a window for a downgrade attack or session hijacking on an untrusted network. HSTS tells the browser to skip HTTP entirely and go straight to HTTPS for every future visit, no exceptions, for as long as the policy's max age specifies.

Set the max age to at least two years and apply the policy across all subdomains, not just the root domain. Submitting your domain to a browser HSTS preload list removes the vulnerable first-request window entirely, even for a visitor who's never been to your site before.

X-Frame-Options and frame-ancestors: shutting down clickjacking

Without framing protection, your site can be loaded inside an iframe on any other domain. An attacker builds a page with your site rendered invisibly underneath a fake button or form, and tricks a user into clicking through to an action they never intended to take, a password change, a fund transfer, a permission grant. This is clickjacking, and it's still common on sites that never explicitly set framing rules.

X-Frame-Options is the legacy header, still worth setting for older browser support, but the frame-ancestors directive inside CSP is the modern replacement and takes precedence where supported. Deny framing entirely unless you have a specific, known reason to allow it from a particular origin, in which case name that origin explicitly rather than leaving the policy open to anyone.

X-Content-Type-Options: stopping MIME sniffing

Browsers will sometimes try to guess a file's actual content type by inspecting its bytes rather than trusting the declared content type, a behavior called MIME sniffing. That guessing can be manipulated. A file uploaded as an image, for example, can be crafted to also be valid, executable script, and a browser that sniffs the content type wrong will execute it instead of rendering it as an image. This one header shuts that behavior off entirely, with a single fixed value and no legitimate reason to omit it.

Referrer-Policy: controlling what leaks in the URL

When a user clicks a link from your site to another domain, the browser can send your full URL, including query parameters and paths, in the referrer information of that outbound request. If your URLs ever contain session tokens, internal identifiers, search terms, or anything sensitive in the path or query string, an unset referrer policy means that data leaks to every external site your users click through to, including ad networks and analytics scripts embedded on the destination page.

The safest practical default sends your full URL on same-origin requests, but trims to just the domain on cross-origin requests, and drops the referrer entirely when a connection downgrades from HTTPS to HTTP.

Permissions-Policy: locking down browser APIs you don't use

Permissions-Policy controls which browser features, camera, microphone, geolocation, USB, payment APIs, a page and any embedded third-party content is allowed to request. Without it, a compromised or malicious third-party script embedded on your page, an ad, a widget, a tracking pixel, can attempt to access hardware APIs your site never intended to expose.

Disable every feature your site doesn't actively use, for your own page and any framed content. If your site genuinely needs one of these APIs, scope it explicitly to your own origin rather than leaving it open by default.

Finding out what's actually missing

Checking six headers manually against your live site works, but it's slow and easy to get wrong, especially across multiple subdomains or after a deploy pipeline changes your server configuration without anyone noticing. Ceron Check runs this exact audit in seconds: enter a public URL and it inspects your security headers, cookie flags, CORS configuration, and transport and redirects in one pass, with each finding backed by evidence, a plain explanation of why it matters, and a specific fix, prioritized by severity so you know what to patch first. It's free, requires no login, and only reads what's already publicly visible to any visitor's browser.

Headers are the floor, not the ceiling

Getting all six headers correctly configured closes off an entire category of browser-based attacks, XSS execution, clickjacking, MIME confusion, referrer leakage, unauthorized API access, for the cost of a few changes in your server configuration. It's one of the highest-value, lowest-effort fixes available in web security, which is exactly why it's worth checking first, before spending time or budget on anything deeper.

Back to the blogExplore Ceron