Datahorses

HTTP security headers every business website should send

By · · 4 min read

HTTP security headers are instructions your web server sends with every page. They tell the browser how to treat your site: always use HTTPS, do not let other sites put your pages in a frame, do not guess file types, load scripts only from places you trust. They cost nothing in performance and are set once in the server or CDN configuration.

The short answer for most business websites: send Strict-Transport-Security, Content-Security-Policy (at least with frame-ancestors), X-Content-Type-Options, Referrer-Policy and Permissions-Policy, set cookies with the right flags, and remove headers that reveal your software versions. The recommended values below follow the OWASP HTTP Headers Cheat Sheet and MDN.

Missing headers are rarely an emergency on their own. They are a sign of how carefully a site is configured, and they close off whole classes of browser-side attacks.

How to check your headers

Ask the server for the headers of your home page:

curl -sI https://yourcompany.com/

Check every hostname, not just the main one: shop, login, customer portal, and any old staging servers that still answer. Headers set in the application often disappear on error pages, redirects and static files, so test a few different URLs.

The headers worth sending

Strict-Transport-Security (HSTS)

Tells the browser to use only HTTPS for your domain for a set time, so a visitor cannot be quietly downgraded to HTTP.

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

max-age is in seconds. Add includeSubDomains only when every subdomain works over HTTPS. To be included in browser preload lists, hstspreload.org requires max-age of at least 31536000 (one year), includeSubDomains and preload. Preloading is hard to undo, so add it last.

Content-Security-Policy (CSP)

Lists the sources from which the page may load scripts, styles, images and frames. A good policy is the strongest browser-side defense against cross-site scripting, but it must be fitted to your site. Start in report-only mode with Content-Security-Policy-Report-Only, watch what would be blocked, then enforce.

Even before a full policy, one directive is easy and useful:

Content-Security-Policy: frame-ancestors 'self'

frame-ancestors controls which sites may embed your pages, which blocks clickjacking. It must be sent as a header; it does not work in a <meta> tag.

X-Frame-Options

The older way to block framing. OWASP recommends frame-ancestors where possible and X-Frame-Options: DENY (or SAMEORIGIN) as a fallback for older browsers.

X-Content-Type-Options

X-Content-Type-Options: nosniff

Stops the browser from guessing a file's type, so an uploaded file cannot be run as a script. Make sure your Content-Type headers are correct across the site.

Referrer-Policy

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

Limits how much of your URLs is passed to other sites when visitors click links. It matters when URLs contain order numbers, tokens or search terms.

Permissions-Policy

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

Turns off browser features your site does not use, so an injected script cannot request them.

Cookies need flags too

Session cookies should be set with Secure (HTTPS only), HttpOnly (not readable from JavaScript) and SameSite=Lax or Strict:

Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax; Path=/

Also check the cookie's Domain. A cookie scoped to .yourcompany.com is readable by every subdomain, which matters if one of them is ever taken over through a dangling DNS record.

Headers to remove or stop using

  • Server and X-Powered-By with version numbers, such as Apache/2.4.41 or PHP/7.4.3. They tell anyone exactly which software and version to look up. OWASP recommends removing X-Powered-By and making Server uninformative.
  • X-XSS-Protection. MDN marks it deprecated and non-standard and notes it can create problems in otherwise safe sites. OWASP recommends not setting it, or setting X-XSS-Protection: 0, and relying on CSP.
  • Expect-CT. OWASP advises not to use it and to remove it from existing configurations.

Where to set them

Set headers in one place that covers every response: the web server (nginx add_header ... always;, Apache Header always set), the CDN or the hosting platform's header settings. The always keyword in nginx matters: without it, headers are added only to successful and redirect responses, not to error pages.

A short checklist

  • Run curl -sI against every hostname you own.
  • Add HSTS, X-Content-Type-Options, Referrer-Policy, Permissions-Policy and frame-ancestors.
  • Roll out a full CSP in report-only mode first.
  • Set Secure, HttpOnly and SameSite on session cookies.
  • Remove version numbers from Server and X-Powered-By, and drop X-XSS-Protection and Expect-CT.
  • Recheck after every server, CDN or platform change.

While you are in the server configuration, also make sure it does not serve exposed .env, .git or backup files.

Where Guarding fits

Guarding watches your websites from the outside every day and checks what browsers and attackers receive: missing security headers, cookies without Secure, HttpOnly or SameSite, servers that reveal their versions, and mixed HTTP content on HTTPS pages. We do not enter your systems and need no access, and each finding includes the exact configuration change for your developer. See the full list of what we guard or request a proposal.

More articles

All articles