SINGAPORE, 11 AUG 2026 — Yesterday we reported that a misconfigured signup form at Klaviyo sent people's passwords to six advertising companies for nearly two years. We ended by asking a question of our readers: do you know what your own trackers collect? For most organisations, nobody has ever looked.
So we looked at ours. Two scripts load on this site before a visitor consents to anything. We authorised one of them.
The method, so you can repeat it
Everything below was measured on 11 August 2026 and takes about five minutes on any site.
Open the site, clear localStorage, sessionStorage and every cookie, then navigate again so the page loads as it would for somebody who has never visited. Before touching the consent banner, read performance.getEntriesByType('resource') and count what came from hosts other than your own. Then read the Content-Security-Policy header and check whether the things you just observed are actually in it.
That is the whole procedure. It is worth doing because the results are not derivable from your codebase — the part we got wrong.
What we found
Thirty-three requests on a first load of the news index. Thirty-one of them first-party. No cookies set before consent, and no consent record written.
The two third-party scripts were www.googletagmanager.com, which loads Google Analytics 4, and static.cloudflareinsights.com, which is Cloudflare's browser performance beacon.
What is working, which matters as much
Three things came back clean and it would be dishonest to bury them under the failure.
There are no third-party asset CDNs at all. Every stylesheet, every font file, every script we wrote and every image is served from our own domain, which is what this project's self-hosting rule requires and it holds without exception.
The consent implementation is correct. On a first visit the tag layer receives a default of denied for analytics storage, ad storage, ad personalisation, ad user data and functionality storage, with only security storage granted, and a 500 millisecond wait for an update. Nothing is granted until a stored choice says so. That is Google Consent Mode v2 implemented the way the documentation describes, and it is the difference between loading a tag and firing one.
And after that page load, no cookies existed on the machine. Not ours, not Google's. For a site that runs any analytics, that is the correct outcome.
The script we did not authorise
This project's rules name exactly two permitted third-party endpoints: Google AdSense for ad serving, and Google Analytics 4 for telemetry. Both are described as narrow exceptions to a rule that otherwise forbids loading anything from anybody else.
Cloudflare Insights is a third one, and it is not written down anywhere as a decision.
It is also not in our source tree. We do not add that script; it arrives because the CDN in front of the site injects it. The code we ship never references it except in one place, which we will come to.
Now the fair part, because overstating this would be its own failure. Cloudflare documents the beacon as cookieless, and our measurement is consistent with that: no cookies appeared. The data it collects goes to /cdn-cgi/rum — a path on our own domain rather than a third-party host — so a visitor's browser is not opening a connection to an unrelated company. This is not the Klaviyo failure. Nobody's password went anywhere.
It is a third-party script executing in every visitor's browser, before consent, that no document in this project authorises and no engineer here chose. The privacy exposure is small, but the governance failure is total: the rule we wrote says two, and the count is three.
We already knew, and we filed it as noise
This is the failure that generalises.
In our own error-tracking script there is a suppression rule for load failures from that domain, and above it a comment. It says the beacon is Cloudflare's and not our code, that it is one of the most ad-blocked domains on the web so its failures are the visitor's blocker rather than a site fault, and — in parentheses — that it is best disabled at the Cloudflare zone.
Somebody found this in June. They identified it correctly, wrote down the correct remedy, and then shipped the thing they actually needed that day, which was to stop the errors cluttering the dashboard. Two months later the beacon is still loading and the note is still a parenthesis.
That is not negligence and it is not unusual. It is what happens when a finding is a side effect of another task. You fix the immediate problem — the noise — and the underlying finding gets demoted to a comment. Every engineering organisation has some number of these, and the number is unknown because by definition nobody is counting them.
The lesson here is not about our specific tracker inventory. The search worth running is for the known problems, the ones someone already wrote down in a parenthesis.
The policy describes a site we are not running
The second finding is the Content-Security-Policy header, and it is more consequential than the first.
Our CSP is report-only. It logs violations to an endpoint and blocks nothing. We then checked the four third-party endpoints we actually observed against the allowlist that policy declares, and three of the four are not in it.
static.cloudflareinsights.com is not in script-src, which follows from nobody having authorised it. It executes anyway, and the reason is the most interesting thing we found.
The CDN signs its own script with our key
After publishing the first version of this article we went back to establish the injection mechanism properly, and the answer changes what the allowlist means.
Fetching the page with ordinary command-line tools returns no beacon at all. Fetch it with full browser navigation headers and the response is 392 bytes larger and contains this:
<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v4513226..." integrity="sha512-ZE9pZaUXND66..." nonce="JKCLlPxqnyN9Nmz8GUTtJA==" data-cf-beacon='{"version":"2024.11.0","token":"d16c10dd8..."}'></script>
Note the nonce. That is our nonce — the random value our middleware generates per request and puts in our own Content-Security-Policy so that our inline scripts may run.
Cloudflare is reading it out of the policy and stamping it onto the script it injects.
The behaviour is sensible from Cloudflare's side: without it, their feature would break every site that uses a nonce-based CSP. The consequence for the site owner is worth stating plainly. A CSP nonce is a bearer token for script execution. Whoever holds it can run code on your page regardless of what your host allowlist says, and your CDN holds it on every request because it is rewriting the response the nonce travels in.
So our earlier framing was too kind to the allowlist. Adding static.cloudflareinsights.com to script-src would document reality, and removing it would change nothing: the beacon is not being permitted by host, it is being permitted by nonce. Turning the CSP from report-only to enforcing would not stop it either.
The only place this can actually be switched off is the Cloudflare dashboard, which is exactly what the comment in our own code said in June.
analytics.google.com is not in connect-src, and this one is a genuine trap. The allowlist contains https://*.google-analytics.com, which looks like it covers Google Analytics and does not: analytics.google.com is a subdomain of google.com, an entirely different registrable domain, and a CSP host wildcard does not reach across. GA4 sends its page-view collection there. Our policy has never covered the main thing our analytics does.
www.google.com.sg/ads/ga-audiences is not in img-src. That is a Google Ads audience pixel, and it fires when a visitor grants advertising consent. (Correction, 11 August 2026: it violates connect-src as well. The browser sends a pixel or a fetch depending on transport, and both appear in this site’s own csp_reports table.)
A report-only policy exists to be promoted to an enforcing one once it is quiet. Ours is not quiet. The day anybody flips that switch, GA4's collection and the ads pixel will break, all because of a policy written to describe a site that does not exist.
The pixel for an ad product we do not run
One more thing surfaced that we are raising as a question rather than a finding, because we could not resolve it from the outside.
The ga-audiences endpoint is Google's advertising audience-building path. It fires here when ad consent is granted. Meanwhile this project decided during 2026 to stop pursuing AdSense, and no advertising runs on these pages.
So on the evidence available we appear to be contributing audience signal to an advertising system we are not using. That may be a legitimate side effect of the standard GA4 configuration with ad features enabled, in which case the fix is a settings change nobody has made. We are stating what we measured and what we do not know. (Correction, 11 August 2026: describing the remedy as a settings change we could not reach was wrong. gtag('config') had never set allow_google_signals — the tag-level switch, which is what actually governs what the browser sends — so it was fixable in our own code all along. That flag and allow_ad_personalization_signals are now false on both initialisation paths, and the change is live on this site as of today.)
What we are changing
Disabling the Cloudflare beacon at the zone, which is what our own comment recommended in June, and either documenting it as a third exception or removing it. A rule that permits two things while three are running is just a number.
Correcting the CSP allowlist so it describes the site as measured rather than as imagined, including analytics.google.com under connect-src. A report-only policy that is never reconciled against reality is just a file, not a control.
And reviewing whether the ad-signal features in our analytics configuration should be on at all, given there is no advertising to serve.
What to run on your own site
Clear your storage, load your own front page, and count the hosts before you touch the banner. If the number is higher than the number of third parties you can name from memory, the gap is your answer and it took five minutes to find.
Then read your own CSP against what you just observed. Most sites we have looked at have a policy written once, at launch, against an inventory that has since changed. A report-only policy generates a comforting quantity of logs that nobody reads.
The Klaviyo failure was worse than ours by a wide margin, and it began in the same place: a page doing something with third-party code that nobody had checked recently. We asked the question in public yesterday, so it seemed only fair to answer it about ourselves first, and publish the answer whichever way it came out.