ePrivacy Art. 5(3) prohibits storing information on a device for any purpose not disclosed at the time of consent. GDPR Art. 5(1)(a)'s transparency principle and CWE-359 (exposure of private information) both apply when cookies are set that users have not been told about. Google Tag Manager is a common source of shadow cookies: a new tag added to the GTM container can set cookies without any code change, making code review an insufficient audit method. A/B testing and session recording tools are frequently added by marketing teams without coordinating with the consent setup, creating undisclosed collection that continues silently.
Medium because unclassified cookies represent undisclosed processing that violates ePrivacy Art. 5(3) and GDPR Art. 5(1)(a), but the impact is typically narrower than the primary consent failures upstream.
Validate at runtime that every cookie present in document.cookie has a corresponding registry entry. Run this check in development or CI to catch gaps before they reach production.
// src/lib/cookie-audit.ts — dev/CI only
import { COOKIE_REGISTRY } from './cookies/registry'
export function auditCookies(): void {
const setCookies = document.cookie
.split(';')
.map(c => c.trim().split('=')[0])
.filter(Boolean)
const registered = COOKIE_REGISTRY.map(e => e.name)
const unclassified = setCookies.filter(
c => !registered.some(r => c.startsWith(r.replace('*', '')))
)
if (unclassified.length > 0) {
console.warn('[cookie-audit] Unclassified cookies found:', unclassified)
}
}
For GTM, audit the container directly: GTM → Admin → Container → Tags. Every tag that fires on All Pages and sets cookies must have a corresponding registry entry.
ID: cookie-consent-compliance.cookie-classification.no-unclassified-cookies
Severity: medium
What to look for: This is the inverse of the previous check. Rather than asking "are all cookies in the registry?", ask "are there any cookies being set that are NOT in the registry?" Check: (1) scan all document.cookie = calls and Set-Cookie server headers and compare against the registry — any cookie set by first-party code must have a registry entry. (2) Look at the consent platform's "auto-scan" results if Cookiebot or OneTrust is in use — these platforms can discover cookies set by your pages in a browser sandbox, often finding more than code review alone reveals. (3) Check whether Google Tag Manager is in use — if so, any tag added to GTM can set cookies without appearing in the codebase. Flag this as a risk requiring GTM container auditing. (4) Check for A/B testing tools (Optimizely, VWO) and session recording tools (FullStory, LogRocket) which set their own cookies and are frequently missed in consent registries.
Pass criteria: Count all cookies and classify each as essential, analytics, marketing, or functional. Every cookie identified during analysis (code review + third-party script inventory) has a corresponding entry in the cookie registry. No unclassified or undocumented cookies are set. 0% of cookies may be unclassified.
Fail criteria: Cookies are set by application code or loaded third-party scripts that have no entry in the cookie registry. GTM is in use with no GTM container audit documented — unknown tags may be setting undisclosed cookies.
Skip (N/A) when: Application sets no cookies (already skipped at all-cookies-documented).
Detail on fail: Example: "A/B testing tool (Optimizely) found in dependencies, sets __opto and _optlz cookies, but neither appears in the cookie registry." or "GTM tag GTM-XXXXXXXX is present. GTM container not audited — unknown tags may set undisclosed cookies.".
Remediation: Validate your registry against actual cookies in src/lib/cookie-audit.ts:
// Compare runtime cookies against registry
const setCookies = document.cookie.split(';').map(c => c.trim().split('=')[0])
const registered = Object.keys(COOKIE_REGISTRY)
const unclassified = setCookies.filter(c => !registered.includes(c))
if (unclassified.length > 0) console.warn('Unclassified cookies:', unclassified)
For GTM: audit the container directly (GTM > Admin > Container > Tags).