I scanned 1,775 websites for GDPR consent leaks. Here's what fires before you click anything
Cookie banners are everywhere. Actual consent, it turns out, is not. I run a small consent tool, and I kept seeing the same thing on customer sites: a banner sitting politely at the bottom of the page while Google Analytics had already fired, set its cookie, and phoned home. The banner was theater. The tracking happened on load, before anyone clicked a thing. So I built a scanner to measure how common that actually is, pointed it at 1,775 real websites, and logged exactly what loaded before consent. Here are the numbers, how the detection works, and the caveats that keep the numbers honest.
The one number that matters
On 30% of sites, a real tracker fired before any consent was given. "Real tracker" is doing work in that sentence, so let me be strict about it. I only count a site as leaking when:
- a known tracker set a cookie before consent, or
- a Google tag ran with consent granted (not in Consent Mode's denied state).
Cookieless tags do not count. Google Consent Mode sitting in its denied state does not count. Privacy-first analytics like Plausible does not count. Those are exactly the setups we want sites to move toward, so counting them as violations would be dishonest and would inflate the number. That makes 30% a floor, not a headline-grab.
The timing is the whole violation. Under GDPR and ePrivacy, non-essential trackers are not supposed to run until the visitor has made a real choice. A tracker that sends identifying data on page load has already done the thing consent was supposed to gate. A banner that appears half a second later is too late to matter.
How the scanner detects a "leak"
The core idea is simple: load the page like a first-time visitor with no consent given, and watch what happens at the network and storage layer before any interaction. I use Puppeteer (headless Chromium) and instrument three things: requests, cookies, and storage writes.
const browser = await puppeteer.launch({ headless: "new" });
const page = await browser.newPage();
const requests = [];
const cookiesBefore = [];
// 1. Capture every outbound request, before any click
page.on("request", (req) => {
requests.push({ url: req.url(), type: req.resourceType() });
});
// 2. Load as a fresh visitor. No consent, no interaction.
await page.goto(targetUrl, { waitUntil: "networkidle2" });
// 3. Read cookies + storage that got set purely on load
const cookies = await page.cookies();
const localStorageKeys = await page.evaluate(() => Object.keys(window.localStorage) );
await browser.close();
Then every request, cookie, and storage key gets matched against a library of tracker definitions. Each definition is roughly:
{
id: "google-analytics",
owner: "Google",
category: "analytics",
risk: "high",
// domains the tag talks to
domains: [/google-analytics\.com/, /analytics\.google\.com/, /googletagmanager\.com/],
// cookies that prove it actually ran, not just loaded
cookies: [/^_ga/, /^_gid/, /^_gat/],
}
The cookie regexes are the important part. A script tag existing in the HTML is not a leak. A script tag that executed and wrote _ga before consent is. Matching on the cookie (or on a Google tag firing with consent granted) is what separates "this site embeds Analytics" from "this site is leaking."
Detecting whether a site even has a consent tool is a separate check: look for known CMP scripts, plus the IAB standard __tcfapi signal on window.
const hasCMP = await page.evaluate(() => {
if (typeof window.__tcfapi === "function") return true;
// fall back to known CMP globals / script signatures
return Boolean(window.OneTrust || window.Cookiebot || window.Cookieyes);
});
That signal is also the source of the biggest caveat, more on that below.
What the 1,775 sites actually showed
Most sites have no visible consent layer. On 82% I could not detect any CMP. Some of those hand-roll a banner I can't fingerprint, so treat 82% as a ceiling. But it still points to a lot of sites with nothing gating their tags.
A banner does not fix it. This was the counterintuitive one. Among sites that did have a detectable CMP, 37% still leaked a tracker before consent. Among sites with no CMP, it was 28%. Installing a banner correlated with more leaking, not less. Two things explain that. Sites that bother installing a CMP tend to be heavier-tracking sites to begin with, so they have more to leak. And a banner only works if it actually gates the tags. A CMP that loads after Analytics has already fired is decoration. If you use Google tags, the banner also has to be wired to Google Consent Mode v2, or consent state never reaches Google on EU traffic.
Google runs the board. By share of sites:
| Owner | Share of sites |
|---|---|
| Google (Analytics, GTM, Ads) | 51% |
| Meta (Pixel) | 9% |
| Microsoft (Clarity, Ads) | 7% |
| LinkedIn Insight | 4% |
| Matomo | 3% |
Narrow it to trackers that actually set a cookie before consent and Google still leads by a mile at 22% of all sites, Meta next at 5%, everything else in low single digits.
These are the tags people paste in during setup and never touch again. It's the boring tags, not exotic ones. Analytics showed up on 50% of sites, advertising on 34%. Marketing tools and social widgets trailed far behind. The good news hidden in that: if you handle Google Analytics, Google Ads, and Meta Pixel correctly, you've covered most of the real-world risk.
Average trackers per site: 1.6. That sounds low until you remember many sites loaded zero. About 58% ran at least one, and among those the count climbs fast. The heaviest single page ran 16 separate trackers.
Two caveats I won't hide
- This is not a random sample of the web. People scan a site because they suspect a problem, so the group skews toward sites with something to find. The percentages describe "sites someone was worried about," not "the average website."
- Custom banners are invisible to detection. I fingerprint CMPs by known scripts and
__tcfapi. A hand-coded banner with no standard signal gets counted as "no CMP." So the no-CMP figure is an upper bound, not a hard count.
I'd rather state both up front than let the numbers imply more than they support.
What to actually do about it
If you build websites, the practical takeaway is short:
- The violation is timing, not the presence of a tag. Audit what fires on load, before any click.
- Start with Google and Meta tags. That's where nearly all the real risk is.
- If you use a banner, confirm it actually gates scripts (lazy-inject after consent) instead of just rendering on top of tags that already fired. For Google tags specifically, wire it to Consent Mode v2.
The easiest way to see where you stand is to load your own site as a fresh visitor and watch the network + cookies before you interact. You can do it by hand in DevTools, or with a scanner.
Disclosure: I work on Consentify, the consent tool this scanner grew out of. The scanner itself is free to run on any domain at consentify.app/scan, and the full write-up of this dataset (it updates as more sites get scanned) lives here.
Comments
No comments yet. Start the discussion.