hello@datascale.de+49 89 921 35 623tracked cookie-free · /openDEEN

Search services, integrations and blog posts.

DatascaleResourcesChecksSecurity headers

Check · C06 · Security & bots

Security headers check: HSTS, frame protection and CSP in the response

The check reads three headers of the scanned page: HSTS, X-Frame-Options or frame-ancestors, and a Content Security Policy. One missing means "to review".

What we check

The scan reads the response headers of the scanned URL after the last redirect. Three things count: Strict-Transport-Security, a protection against framing (X-Frame-Options or a CSP with frame-ancestors), and a Content-Security-Policy. All three set means "ok". If one is missing, the line names what is there and what is not, and reads "to review". If all are missing, also "to review", marked as a weak baseline.

What the scan does not rate: the content of the headers. A CSP with default-src * counts as set, so does an HSTS with a one-second lifetime. Further headers such as Referrer-Policy, Permissions-Policy or X-Content-Type-Options stay out of scope, as do subpages and static assets that a CDN may serve with different headers.

Why it matters

The CSP is the header where tracking and IT meet. It decides which scripts run, and every new tag endpoint has to be in it: the tag manager, the server-side container on your own subdomain, the CMP, the pixels after that. One missing entry and the browser blocks silently, the data flow stops, and in reporting that looks like a campaign problem. We have been there ourselves: for weeks the live configuration of datascale.de lacked data: in script-src while the repository carried the right policy. The difference was visible only in the response, nowhere in the code.

HSTS makes sure the browser never requests the page over HTTP again after the first visit. Frame protection stops someone from loading your page inside a foreign frame and harvesting clicks. Both are baseline, not a project.

Common causes

  • The host serves default headers; nobody ever configured a security policy.
  • A CSP existed, but after frontend errors it was removed entirely instead of repaired.
  • A proxy or CDN overwrites the headers set by the backend on delivery, or sets them only for dynamic pages, not for statically cached ones.
  • The headers live in the application, but the static pages come straight from the web server or the edge and do not carry them.

The fix

Set the headers where every response passes through, usually at the reverse proxy or CDN, not in the application. Order: Strict-Transport-Security with at least a one-year lifetime, then frame-ancestors 'self' in the CSP, then the CSP itself, first as Content-Security-Policy-Report-Only with all tag endpoints, enforced after a week without violations. Then curl -I against the live domain. Read the response, not the config file. A grade B on securityheaders.com is a realistic target for a marketing site; A demands a strict CSP that turns every new tag into a ticket.

Check it yourself first

The Tracking Check tests this point along with all the others, in seconds.

Start the Tracking Check →
Why does a tracking check look at security headers at all?

Because of the CSP. A Content Security Policy decides which scripts the browser executes, and with that whether tag manager, consent platform and server-side endpoint load at all. A CSP that does not know the new tagging server switches tracking off silently; in the dashboard that looks like a conversion drop. The other two headers are the baseline every audit asks for anyway.

We have a CSP, but it breaks our tracking. What now?

Run it in report-only mode first: the browser reports violations but blocks nothing. Then add the tag endpoints: the tag manager, your own tagging server, the CMP CDN and the pixels that load after consent. Use a nonce for inline snippets instead of "unsafe-inline". Only once the report is empty, enforce the policy.

Is X-Frame-Options enough, or do we need frame-ancestors?

Either satisfies the check. "frame-ancestors" in the CSP is the modern route and allows more than "SAMEORIGIN" or "DENY", such as individual partner domains. If you set both, keep them identical in effect; where they contradict, current browsers follow the CSP.

The fix, delivered

Wired up in days, not sprints.

Findings from the Tracking Check go into a ranked sequence with effort estimates in the Audit Sprint, every module with an acceptance criterion.