Security Headers Explained for Small Business Websites

Every time a browser loads a page from your site, your server sends back more than the page itself. It also sends a short list of instructions called HTTP headers. Some of them are boring housekeeping. A handful, the security headers, tell the visitor's browser how strictly to behave while it shows your site.

Think of them as house rules posted at the door: only talk to me over a secure connection, do not let strangers frame this page, do not guess file types. They cost nothing and close off whole categories of attack, yet most small business sites have none of them.

This guide explains each header, gives you a safe starting set, and covers the mistakes that cause problems.

First, the foundation: HTTPS

Security headers sit on top of HTTPS, so check that first. HTTPS encrypts the connection between your visitor and your server, so nobody on the same coffee shop wifi can read or change what passes between them. Browsers also label sites without it as "Not secure", which is not what you want next to a contact form.

A quick HTTPS check:

  • [ ] Your site opens with https:// and shows a padlock, with no warnings.
  • [ ] Typing http:// redirects to https:// automatically, in one step.
  • [ ] Your certificate renews on its own. Most hosts do this for free; an expired certificate shows visitors a full-page warning.
  • [ ] No "mixed content": an https page that loads an image or script from an http address. Browsers block or flag these.

If any of those fail, fix them before touching headers. Your host's support team can usually do it in one message.

The headers, one at a time

Strict-Transport-Security (HSTS)

HSTS tells the browser: "For the next while, only ever connect to this site over HTTPS, even if someone types http." It stops a downgrade attack where an attacker on a shared network quietly forces visitors onto the unencrypted version.

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

max-age is how long the browser remembers the rule, in seconds. 31536000 is one year. Careful with includeSubDomains: it applies the rule to every subdomain, so only add it once everything under your domain, such as mail. or shop., works over HTTPS. If you are unsure, start with a short max-age of a day (86400), confirm nothing breaks, then raise it.

X-Content-Type-Options

Browsers sometimes try to be clever and "sniff" a file's real type, ignoring what the server said. An attacker can exploit that by uploading something that looks like an image but runs as a script. This header turns the guessing off.

X-Content-Type-Options: nosniff

There is one possible value and almost no downside. Add it.

Clickjacking protection: X-Frame-Options and frame-ancestors

Clickjacking is when another site loads yours invisibly inside a frame and tricks visitors into clicking buttons they cannot see. The fix is to say who may frame your pages. The old way is X-Frame-Options; the modern way is the frame-ancestors directive inside Content-Security-Policy.

X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'

Both say "only my own site may frame my pages". Use DENY or 'none' if nothing should ever frame them. Sending both is common and harmless; modern browsers prefer frame-ancestors, older ones use X-Frame-Options.

Note what this controls: who can embed your pages. It does not stop you embedding someone else's map or video on your pages. That is governed by a different CSP directive, covered below.

Referrer-Policy

When a visitor clicks a link from your page to another site, their browser tells the new site where they came from. That referrer is a full web address, which can include private details such as a booking reference or search term in the URL. This header limits what is shared.

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

With this value, links to other sites only reveal your domain name, not the full page address, and nothing is sent when going from https to http. Your own analytics still see full addresses within your site. It is a sensible default and is what most modern browsers use anyway, but setting it explicitly makes it consistent.

Permissions-Policy

Browsers can switch on powerful features: camera, microphone, location, payment, motion sensors. Your site, or a script it loads, may ask for them. Permissions-Policy lets you say which features your pages are allowed to use at all. If you never need the microphone, switch it off for everything, including third-party code.

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

Empty brackets mean "nobody, including my own pages". If you do use a feature, such as location for a store finder, allow it for yourself: geolocation=(self).

Content-Security-Policy (CSP)

CSP is the strongest and the most fiddly. It is an allowlist of where your page may load things from: scripts, styles, images, fonts, frames, form targets. If an attacker manages to inject a malicious script into a page, a good CSP stops the browser from running it or sending data to the attacker's server.

A tight example for a simple site that hosts everything itself:

Content-Security-Policy: default-src 'self'; img-src 'self' data:; frame-ancestors 'self'; base-uri 'self'; form-action 'self'

Reading it left to right: by default load only from my own domain; images may also be inline data: images; only I may frame my pages; and forms may only submit to me.

The catch is that real sites use outside services, and every one needs a line in the policy. That is where most CSP problems come from, so it gets its own section below.

A safe starter set

Here is a set that gives real protection with very little risk of breaking a typical brochure or lead-generation site. Add the headers through your host's settings, a configuration file, or ask your developer to do it.

HeaderStarter valueRisk of breaking things
Strict-Transport-Securitymax-age=31536000; includeSubDomainsLow, once all subdomains use HTTPS
X-Content-Type-OptionsnosniffVery low
X-Frame-OptionsSAMEORIGINLow, unless you frame your own pages from another domain
Referrer-Policystrict-origin-when-cross-originVery low
Permissions-Policycamera=(), microphone=(), geolocation=(), payment=()Low, unless you use those features
Content-Security-PolicyStart with frame-ancestors 'self', then build upMedium to high if rushed

Notice the last row. The first five can go live today. For CSP, begin with only the frame-ancestors part, which gives you the clickjacking protection without restricting anything else. Then tighten step by step.

How to check your headers

You do not need special software.

  1. Browser dev tools. Open your site, open developer tools (usually F12), go to the Network tab, reload, click the first request (your page) and look at the response headers.
  2. A header scanner. Several free online checkers will fetch your page and grade the headers, listing what is missing.
  3. Our grader. The free website grader looks at the security basics, including HTTPS and these headers, alongside speed and search checks, and lists what to fix in plain English.

Check the homepage, but also a form page and any page with embeds, since headers can differ by page.

Common mistakes

Breaking embeds with a strict CSP

This is the big one. You add default-src 'self', and suddenly the map on your contact page is a blank grey box, the booking widget has vanished and the video does not play. The browser did exactly what you asked: it blocked everything not on the list.

Embedded content falls under the frame-src directive (or default-src if frame-src is absent). Each outside service you use needs allowing explicitly. For example, if the contact page embeds a map and a video:

frame-src 'self' https://www.google.com https://www.youtube-nocookie.com

The same applies to third-party scripts (script-src), stylesheets and fonts (style-src, font-src), images (img-src), and the places your forms or scripts send data (connect-src, form-action).

How to avoid the breakage:

  • Inventory first. List every outside service on your site: embeds, chat, analytics, fonts, payment buttons, newsletter forms.
  • Test in report-only mode. Send the header as Content-Security-Policy-Report-Only first. The browser logs what it would have blocked without blocking anything. Read the messages in the dev tools console, adjust, and only then switch to the enforcing version.
  • Test every page type with embeds, not just the homepage.
  • Avoid 'unsafe-inline' and 'unsafe-eval' as a quick fix. They make the errors vanish by switching off much of the protection. Use them only as a temporary step if a plug-in forces it, and plan to remove them.

Setting HSTS before HTTPS is solid

Browsers remember HSTS. If you set a one-year rule and your certificate then expires, visitors cannot click through the warning; the site is simply unreachable. Make sure certificates renew automatically before you raise max-age.

Copying headers blindly

A header block pasted from a forum may block features your site relies on, or break an old staging. subdomain under includeSubDomains. Understand each line, or test on a copy first.

Treating headers as the whole job

Headers are a seatbelt, not a lock on the door. They do not replace updates, strong passwords, two-step login and backups. Our small business website checklist covers those basics, and website speed for small business explains why unused plug-ins and scripts are worth removing for performance as well as safety.

A 30-minute plan

  1. Check HTTPS (5 min). Padlock, single redirect, one canonical address.
  2. Add the easy five (15 min), with a short HSTS max-age at first, plus frame-ancestors 'self'.
  3. Retest and click around (10 min). Forms, maps, videos. Then raise the HSTS max-age.
  4. Later, build the full CSP in report-only mode over a week or two.

Next step

Find out which headers your site is missing today: grade your website and work through the security results. If you would rather have a site that ships with sensible defaults from day one, Belmo Studio will make you a free preview, and you only pay if you like it.

Grade my website free