Skip to main content

Cookie consent banner present when tracking is in use

ab-002581 · project-snapshot.legal.cookie-banner-when-tracking
Severity: mediumactive

Why it matters

Loading PostHog, Google Analytics, Segment, Mixpanel, or Hotjar before an EU/UK visitor clicks "accept" violates GDPR Art. 7 and the ePrivacy Directive — regulators have issued five- and six-figure fines (CNIL v. Google, €150M; ICO enforcement against Easylife, Clearview) specifically for tracking-before-consent. AI coding tools ship the classic failing shape: a posthog.init() or <Script src="googletagmanager.com/..."> dropped into app/layout.tsx during setup with no consent gate wired in, because the assistant knew how to install the SDK but not the regulatory dependency. The user-facing failure is silent — the site works, cookies get dropped, and the liability accrues until a complaint or audit surfaces it. California CPRA, Quebec Law 25, and Brazil's LGPD impose parallel prior-consent requirements.

Severity rationale

Medium because the legal exposure is real and per-visitor but remediation is a narrow code change (gate `init()` on a consent token) rather than a re-architecture; the failing shape is recoverable in hours, not sprints.

Remediation

Add a consent banner that gates tracking init:

if (consent === 'granted') posthog.init(KEY, { autocapture: true })

Use a library like react-cookie-consent or vanilla-cookieconsent for the UI.

Deeper remediation guidance and cross-reference coverage for this check lives in the gdpr-readiness Pro audit — run that after applying this fix for a more exhaustive pass on the same topic.

Detection

  • ID: project-snapshot.legal.cookie-banner-when-tracking
  • Severity: medium
  • What to look for: Detect tracking presence: package.json deps for posthog-js, @vercel/analytics, @segment/analytics-next, mixpanel-browser, react-ga, react-ga4, @google-analytics/data, @hotjar/browser, Plausible/Fathom snippets in layout/head. Also detect script tags containing googletagmanager.com, google-analytics.com, fbevents.js. If any tracking is detected, look for a cookie consent banner: imports of react-cookie-consent, vanilla-cookieconsent, cookie-consent-banner, or in-house components in components/cookie-banner.tsx / app/cookie-banner.tsx. Count tracking sources and consent surfaces.
  • Pass criteria: Either no tracking is detected, OR tracking is present AND a consent banner is rendered before tracking initializes.
  • Fail criteria: Tracking detected and no consent banner found.
  • Skip (N/A) when: No tracking detected. Quote: "No analytics dependencies or tracking script tags detected."
  • Do NOT pass when: A consent banner exists but tracking initializes regardless of consent (e.g., useEffect(() => posthog.init()) runs without checking consent state).
  • Report even on pass: "Tracking detected: {libraries}; consent banner: {component or library}; analytics initializes after consent."
  • Detail on fail: "PostHog detected (posthog-js in deps, posthog.init in app/layout.tsx); no cookie consent banner found".
  • Cross-reference: For full GDPR coverage (data-subject rights, DPAs, breach-notification flows, retention policies), run the gdpr-readiness audit.
  • Remediation: Add a consent banner that gates tracking init:
    if (consent === 'granted') posthog.init(KEY, { autocapture: true })
    
    Use a library like react-cookie-consent or vanilla-cookieconsent for the UI.

Taxons

History