Security Headers Checklist for Business Sites
Seven HTTP response headers that close the most common attacks on a business website, what each one actually does, and how to check the ones you are already sending.

Headers are the cheapest security you will ever deploy
Every response your server sends carries headers. A handful of them tell the browser how to treat your site, and setting them correctly closes off a whole class of attacks without touching a line of application code.
They are not a substitute for the rest of security. They do nothing about a weak password, an unpatched dependency or an endpoint with no authorisation check. What they are is the highest return per hour of work available on a business website, and most business websites send almost none of them.
You can see what you are sending right now with the security headers checker, which fetches your live URL and reports what came back. Everything below is one of the things it looks for.
Start with HTTPS, then make it non-negotiable
HTTPS is assumed at this point, but two things around it are routinely left half done.
The first is the certificate itself: valid, not expiring in three weeks, and covering every hostname you actually serve, which usually means both example.com and www.example.com. Certificates that expire on a Sunday are a genuine cause of outages. The SSL checker will tell you what yours covers and when it expires.
The second is Strict-Transport-Security, usually called HSTS. Redirecting HTTP to HTTPS still allows a first insecure request, and that first request is where an attacker on the same network can intervene. HSTS tells the browser never to attempt HTTP for your domain again:
Strict-Transport-Security: max-age=31536000; includeSubDomainsOne warning worth respecting. includeSubDomains applies to every subdomain, including internal ones you may have forgotten about, and the browser will remember the instruction for the full max-age. Start with a short max-age, confirm nothing broke, then raise it. The HSTS checker shows what you are currently sending.
Content-Security-Policy
CSP is the most powerful of these headers and the most work, because it is the one that says which sources of script, style, image and font the browser is permitted to load. Done properly it means an injected <script> tag does not execute, which is the difference between a defacement and a breach.
It is also the one that breaks sites when it is pasted in from a blog post, so do it in this order:
- Deploy it as
Content-Security-Policy-Report-Onlyfirst. The browser reports what would have been blocked and blocks nothing. - Live with that for a week and read the reports. You will discover third-party scripts nobody remembers adding.
- Tighten until the report is quiet, then switch to enforcing.
Avoid unsafe-inline if you possibly can, because it removes most of the benefit. If your site has inline scripts it cannot lose, use a nonce rather than opening the whole category. The CSP analyzer will parse a policy and point out the directives that are weaker than they look.
X-Content-Type-Options
X-Content-Type-Options: nosniffOne line, no configuration, no downside. It stops the browser from guessing that a file is something other than what you said it was, which is how an uploaded file that claims to be an image ends up being executed as script. If you set nothing else from this article, set this.
Referrer-Policy
By default, when a visitor clicks a link off your site, the browser tells the destination which page they came from, including the full URL. On a site with query strings, tokens or internal search terms in URLs, that is a quiet leak to every external site you link to.
Referrer-Policy: strict-origin-when-cross-originThis sends the full path within your own site, and only the bare domain to anywhere else. It is the sensible default for a business site and it keeps analytics working.
Permissions-Policy
This declares which browser capabilities your pages are allowed to use. A business website almost never needs the camera, the microphone, geolocation or payment APIs, and saying so explicitly means an injected script cannot request them either.
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()Start from denying everything and add back what the site genuinely uses.
Clickjacking: frame-ancestors, not X-Frame-Options
Clickjacking is loading your site inside an invisible frame on an attacker's page so that a user who thinks they are clicking one thing clicks another. The old defence was X-Frame-Options: DENY. It still works, and it is still worth sending for old browsers, but the modern and more flexible answer is a CSP directive:
Content-Security-Policy: frame-ancestors 'self'Send both. They cost nothing and they cover different browsers.
Email is a security surface too
Headers protect the website. The other half of a business domain is email, and a domain with no email authentication can be spoofed by anybody, which is how invoice fraud reaches your customers with your name on it.
Three records, all in DNS:
- SPF lists which servers may send mail as your domain.
- DKIM signs outgoing mail so the recipient can verify it was not altered.
- DMARC tells receiving servers what to do when a message fails the first two, and where to send reports.
Check what you publish with the DMARC checker. A great many business domains have SPF, no DKIM, and a DMARC policy of p=none, which requests reports and enforces nothing. That is a reasonable place to start and a poor place to stay. When the symptom is your own mail landing in junk rather than somebody forging you, why business emails go to spam walks the diagnosis in order, including the records your website sends from rather than your mailbox.
The same three records decide whether your own mail is believed, which is why a neglected domain tends to produce the other symptom at the same time: enquiries that never arrive. If that is happening to you, contact form emails going to spam splits it into the three faults it can be and diagnoses each one from the browser.
What this does not cover
Being honest about the limits matters more here than in most subjects, because security is the area where confident marketing does the most damage.
Headers do not authenticate anybody. They do not authorise anybody. They do not patch your dependencies, protect a database with a default password, or stop a member of staff pasting credentials into a message. They close specific browser-level attacks and nothing else.
They are also not a certification. BitsSolved does not hold SOC 2, ISO 27001 or HIPAA attestations, and any vendor who implies that setting headers amounts to compliance is selling something. What we do is set them on everything we deploy, along with TLS, monitoring and backups, and this site passes its own checkers, which is the least you should expect from anybody who publishes a tool like that.
If you want the current state of a site written down rather than guessed at, that is website fixes and maintenance for an existing site, and cloud and DevOps when the answer is in the infrastructure rather than the markup.
Tools mentioned in this post
- Security Headers CheckerScore any site’s security headers. HSTS, CSP, X-Frame-Options and more, with fixes.
- SSL CheckerCheck any site’s SSL certificate: validity, expiry date, issuer and chain.
- HSTS CheckerVerify a site’s Strict-Transport-Security header: max-age, subdomains and preload readiness.
- CSP AnalyzerPaste a Content-Security-Policy: get its directives decoded and its weaknesses flagged.
- HTTP Header CheckerInspect any URL’s response headers and get a security-header report card.


