· via dev.to (home feed)
Cloudflare's edge-injected analytics beacon trips strict CSP setups
A developer reports that Cloudflare's Web Analytics injects beacon.min.js at the edge by default, tripping strict Content-Security-Policy rules on sites that never agreed to run a tracker.

A developer found that Cloudflare's Web Analytics feature silently injects a tracking script into pages served through its network, and that a strict Content-Security-Policy blocks it — producing a console error and a Lighthouse penalty that nudge site owners toward allowing a host they never chose.
According to a post on dev.to, originally published on indiecore.net, the author deployed a site, opened the browser console out of habit, and saw a CSP violation: the browser refused to load beacon.min.js from static.cloudflareinsights.com because the script-src directive only permitted 'self', 'unsafe-inline' and 'inline-speculation-rules'. The script appeared in no template, no build output and no dependency; a grep for cloudflareinsights against the built HTML returned zero matches.
The script is added at the edge, not in the repo
As the post explains, Cloudflare Web Analytics has an automatic mode that is switched on by default when a site is added. It inserts the beacon script into HTML responses at the edge, so neither the origin server nor the codebase ever contains it.
The injection is also selective about clients. Requests made with curl, or with a desktop browser User-Agent string, returned responses without the script. Only an actual browser navigation received it — which is why Lighthouse flagged it while the author's terminal checks stayed clean. The artefact exists in production, is absent from the source, and cannot be reproduced with the command-line tool most people reach for first when inspecting what a server returned.
Nothing was tracked
The CSP worked as intended. The Lighthouse network trace recorded the blocked request with a status code of -1 and a transfer size of zero bytes, meaning the browser matched the URL against script-src, found no permitted source, and refused before opening a connection. No data left the visitor's browser.
The error still carries a cost. A logged console error dropped the Lighthouse Best Practices category from 100 to 92, and the author argues that persistent red lines in the console train developers to ignore red lines in the console.
The obvious fix contradicts the site's promises
Search for the error message and the prevailing advice is to add the Cloudflare insights host to script-src. That silences the console and restores the score in about ten seconds. But the author's privacy policy states that no analytics script of any kind runs in the browser and no request leaves the domain unless a trailer is started. Permitting the host would make that sentence false in the same edit that turned the console green — and nothing in the build would have objected, because the policy is prose, the CSP is a header, and nothing connected the two.
The fix consistent with the policy lives in the Cloudflare dashboard rather than the repository: disabling Web Analytics for the site stops the injection entirely, so the console goes quiet because the script is gone rather than because it was invited in.
A build check that ties policy to headers
To keep the promise enforceable, the author added a build step that reads the privacy policy and, when it claims no analytics, inspects the script-src and connect-src directives in the headers file and fails the build if any external http or https host, or a wildcard, is present. frame-src is deliberately excluded because the site's YouTube trailer embed is the single documented exception named in the policy itself. The author validated the check by temporarily adding the beacon host and watching the build fail, on the grounds that a check never seen failing is not really a check.
Local CI cannot see this
The author's CI pipeline runs Lighthouse against a local static server that serves only the built output — no CDN, no edge features, no injection. Every audit passes at 100, but it measures a directory, while production is that directory plus a CDN with its own behaviour. The author now runs one additional audit against the live hostname after each deploy and reads the console, which is what surfaced the injected script in the first place.
One item remains unresolved. The response headers also configure Network Error Logging, with reports directed at a Cloudflare endpoint. No script executes, so the "no analytics script runs in your browser" wording still holds, but a failed request would send a report to Cloudflare, which sits awkwardly against the policy's claim that nothing leaves the domain. Headers are outside CSP's reach, so nothing in the repository can block it.
Why it matters
This affects any site behind Cloudflare where Web Analytics' automatic mode is on: owners can ship a third-party script they never wrote, never committed and cannot find with grep. A strict CSP will block it, but the visible symptoms — a console error and a lower Best Practices score — steer developers toward allowlisting the host rather than questioning where the script came from. It is also a broader lesson about edge computing: modifications made at the CDN layer are invisible to local builds, curl-based verification and conventional CI, so the only reliable check is auditing the real deployed origin after each release.
- #cloudflare
- #content-security-policy
- #web-analytics
- #privacy
- #cdn