A cookie banner is not proof of compliance.
It is only a user interface.
The real question is whether the browser behaves correctly before and after the user makes a consent choice.
That distinction became even more important after the UK ICO's April 2026 guidance on Storage and Access Technologies. The guidance makes clear that the relevant compliance scope is not limited to HTTP cookies. It includes cookies, tracking pixels, link decoration, local storage, device fingerprinting, scripts, and tags. The ICO also states that PECR applies where scripts and tags store or access information on a user's device, whether or not they are used together with cookies.
In practical terms:
A website can show a compliant-looking consent banner and still fail because tracking technologies fire before consent.
This article explains how to audit that properly.
1. The problem: banner compliance vs browser compliance
Most compliance checks still focus on the visible banner:
| Banner question | Why it is insufficient |
|---|---|
| Does the site show a cookie banner? | A banner can exist while trackers still fire before consent. |
| Is there an "Accept" button? | Consent must also be freely given, specific, informed, and unambiguous. |
| Is there a "Reject" button? | Reject must actually block non-exempt technologies. |
| Is there a cookie policy? | The policy must match real browser behavior. |
| Are cookies listed? | Modern tracking may use pixels, localStorage, scripts, tags, and fingerprinting instead. |
A scientific audit must compare declared behavior with observed behavior.
Declared behavior is what the CMP, privacy policy, or cookie list says.
Observed behavior is what actually happens in the browser: cookies, storage entries, network calls, scripts, tags, and device access.
The gap between those two is where many compliance failures appear.
2. What counts as storage and access technology?
The ICO's SAT guidance is intentionally broad. It covers technologies that store information on a device or access information already stored there. The ICO lists cookies, tracking pixels, link decoration and navigational tracking, local storage, device fingerprinting, scripts, and tags.
That means an audit should not be called a "cookie audit" unless it is only checking cookies.
A modern website audit should cover:
| Technology | What to inspect |
|---|---|
| Cookies | Name, domain, expiry, SameSite, Secure, HttpOnly, creation timing |
| localStorage | Persistent identifiers, analytics IDs, ad IDs, CMP state |
| sessionStorage | Session identifiers, feature flags, temporary tracking IDs |
| IndexedDB | Client-side databases used by analytics, apps, or third-party SDKs |
| Pixels | Image or script requests used for measurement, attribution, retargeting |
| Scripts | Third-party JS loaded before consent |
| Tags | GTM, ad tags, analytics tags, conversion tags |
| Link decoration | gclid, fbclid, affiliate IDs, campaign IDs, click IDs |
| Fingerprinting | Device/browser characteristics used to identify or single out users |
| Network requests | Third-party endpoints contacted before or after consent |
The ICO also explains that tags often use other technologies such as cookies, local storage, or fingerprinting techniques to record and track information about a user.
So the scanner must observe chains of behavior, not just isolated files.
3. The legal logic: prior consent and real choice
Under PECR, storing information on or accessing information from a user's terminal equipment generally requires clear and comprehensive information and consent, unless an exception applies. The ICO explains that non-exempt storage and access technologies must not be used before consent is obtained.
The EDPB's consent guidance under GDPR is also relevant because, where consent is required under ePrivacy-style rules, the GDPR standard of consent applies. The EDPB defines consent as freely given, specific, informed, and unambiguous. It also rejects consent by scrolling or continued browsing as valid consent.
For a scanner, this translates into concrete rules:
| Legal requirement | Technical test |
|---|---|
| Prior consent | Did non-exempt storage/access happen before a click on "Accept"? |
| Freely given | Was rejection available without manipulation or obstruction? |
| Specific | Were analytics, ads, personalization, and other purposes separable? |
| Informed | Were vendors and purposes disclosed before consent? |
| Unambiguous | Was there a clear affirmative action? |
| Withdrawable | Can the user later change or revoke consent? |
| Accountable | Can the organization prove what happened? |
The key point: legal compliance depends on both interface design and technical enforcement.
4. The four consent states every scanner should test
A serious audit should not test only one browser state.
It should run controlled tests across at least four states.
| State | Purpose |
|---|---|
| No choice / pre-consent | Detect what happens before the user interacts with the banner. |
| Reject all | Verify that refusal blocks non-exempt technologies. |
| Accept all | Establish the full tracking baseline after consent. |
| Withdrawal / change choice | Verify that the user can reverse consent and stop future non-essential tracking. |
For advanced audits, add two more:
| State | Purpose |
|---|---|
| Granular consent | Test whether analytics, advertising, personalization, and functional categories behave separately. |
| Return visit | Verify that the previously stored consent choice is respected. |
This is important because many sites pass the first page-load test but fail after a state change.
Example:
- The site loads cleanly before consent.
- The user accepts all.
- The user later withdraws consent.
- The website stops setting new cookies but leaves localStorage tracking IDs active.
- Third-party scripts continue firing because tag-manager rules were not updated.
That is not a banner problem. It is a consent-state enforcement problem.
5. What to capture during the scan
A good scanner should produce evidence, not only a pass/fail label.
5.1 Browser storage evidence
Capture storage before and after each consent action.
| Evidence | Why it matters |
|---|---|
| Cookie name | Identifies the technology |
| Domain | Shows first-party or third-party scope |
| Expiry | Distinguishes session vs persistent tracking |
| Creation timing | Shows whether it appeared before or after consent |
| Value pattern | May reveal identifiers, consent strings, session tokens |
| localStorage key/value | Detects non-cookie identifiers |
| sessionStorage key/value | Detects temporary tracking or feature state |
| IndexedDB names | Reveals SDKs, offline storage, analytics databases |
The scanner does not always need to expose full values in a public report. For privacy and security, values can be hashed or redacted. But the audit should still record enough evidence to prove that storage existed and when it appeared.
5.2 Network evidence
Network requests are often more important than storage.
A pixel can fire without leaving a persistent cookie. A script can send browser metadata before creating any visible storage entry. A tag can redirect through multiple domains before consent.
Capture:
| Field | Example use |
|---|---|
| URL | Identify endpoint and vendor |
| Domain | Classify first-party vs third-party |
| Request method | GET, POST, beacon, image, script |
| Resource type | document, script, image, fetch, xhr, beacon |
| Timestamp | Compare against consent action |
| Initiator | Identify which script triggered it |
| Request payload | Detect event names, campaign IDs, user IDs |
| Response headers | Detect Set-Cookie or tracking redirects |
This is where many "cookie-compliant" sites fail: no cookie appears, but tracking requests still happen.
5.3 Script and tag evidence
Scripts and tags are especially important because the ICO explicitly includes them where they store or access device information.
Capture:
| Evidence | Why it matters |
|---|---|
| Script URL | Identifies third-party libraries |
| Tag manager containers | Shows hidden orchestration layer |
| Script execution timing | Shows whether code runs before consent |
| Initiator chain | Links script to later pixels/storage |
| Vendor relationship | Maps technology to third party or processor |
| Consent category | Confirms whether CMP classification is correct |
Tag managers are common failure points because teams add new tags without updating CMP rules or legal inventories.
6. How to classify findings scientifically
Do not classify findings only by vendor name.
Classify them by observed behavior, purpose, timing, and consent state.
A useful finding model:
| Field | Example |
|---|---|
| Technology type | Cookie, localStorage, pixel, script, tag, fingerprinting signal |
| Vendor | Google, Meta, Microsoft, TikTok, Hotjar, custom endpoint |
| Purpose | Analytics, advertising, personalization, security, functional |
| Consent state | Pre-consent, reject, accept, withdrawal |
| Timing | Before consent, after reject, after accept |
| Evidence | Cookie, storage entry, network call, script load, screenshot |
| Risk level | Critical, high, medium, low |
| Legal concern | Prior consent, transparency, vendor disclosure, dark pattern |
| Recommended fix | Block tag, reclassify vendor, update CMP, remove pre-consent call |
This prevents a common mistake: assuming a vendor is always compliant or non-compliant.
The same vendor may provide both necessary and non-necessary functions. The same script may support security, analytics, and advertising. The same cookie may be first-party but still used for advertising.
Purpose and timing matter more than labels.
7. Failure taxonomy: what your scanner should detect
Failure 1: Pre-consent tracking
Definition: A non-exempt technology fires before the user gives consent.
Examples:
| Evidence | Example |
|---|---|
| Cookie | _ga appears before consent |
| Pixel | Meta Pixel request fires on initial page load |
| localStorage | Visitor ID stored before consent |
| Script | Advertising SDK loads before consent |
| Network | Conversion endpoint called before consent |
Severity: High or critical, depending on purpose and data involved.
Failure 2: Reject does not block
Definition: The user clicks "Reject all", but analytics, advertising, or personalization technologies still run.
This is one of the strongest findings because it proves the interface and technical behavior are inconsistent.
Failure 3: Misclassified technology
Definition: A technology is classified as necessary or functional but performs analytics, advertising, personalization, or behavioral measurement.
Example:
| CMP category | Observed behavior |
|---|---|
| Necessary | Sends page-view events to analytics endpoint |
| Functional | Loads retargeting pixel |
| Performance | Sends ad conversion event |
| Security | Stores cross-site visitor identifier |
Failure 4: Hidden vendor
Definition: A third-party domain appears in the browser but is missing from the cookie policy, CMP vendor list, or privacy notice.
This creates a transparency problem because users cannot make an informed choice if the real vendors are not disclosed.
Failure 5: LocalStorage bypass
Definition: Cookies are blocked, but persistent identifiers are written to localStorage or another browser storage mechanism.
This is exactly why audits must go beyond cookies.
Failure 6: Link decoration persistence
Definition: Campaign or click identifiers are stored or propagated after landing.
Examples include advertising click IDs, affiliate IDs, campaign IDs, and user journey parameters. Link decoration can be part of attribution and tracking, so it should be inspected under storage/access and transparency rules.
Failure 7: Consent withdrawal failure
Definition: The user changes their choice from accept to reject, but existing tracking remains active or new tracking continues.
This is often missed because many audits test only the first page load.
Failure 8: Deceptive consent design
Definition: The interface manipulates the user into accepting.
The EDPB's deceptive design pattern guidance treats misleading, detrimental, or manipulative interface behavior as relevant to fairness, transparency, accountability, and data protection by design.
Examples:
| Pattern | Audit signal |
|---|---|
| Obstruction | Reject requires more clicks than accept |
| Visual pressure | Accept is prominent, reject is hidden |
| Ambiguity | Buttons use vague wording like "Continue" |
| Preselection | Optional categories are enabled by default |
| False necessity | Advertising tools placed under necessary category |
8. A practical scan methodology
Here is a practical step-by-step method for compliance teams and scanner builders.
Step 1: Start from a clean browser profile
Use a fresh context with:
| Setting | Reason |
|---|---|
| No cookies | Prevent old consent states from hiding failures |
| No localStorage/sessionStorage | Detect new storage creation |
| Cache disabled or controlled | Avoid missing script loads |
| Stable region | Consent behavior often differs by jurisdiction |
| Stable device profile | Mobile and desktop may differ |
Run separate tests for desktop and mobile because banners, ad stacks, and video players often differ across devices.
Step 2: Capture initial page state
Before clicking anything:
- Take screenshot of banner.
- Capture all cookies.
- Capture localStorage and sessionStorage.
- Capture network requests.
- Capture third-party scripts.
- Record timestamp.
- Detect CMP and consent categories if available.
This is the most important stage. Anything non-exempt that runs here is a likely pre-consent issue.
Step 3: Classify initial findings
For each detected item, classify:
| Question | Example |
|---|---|
| Is it storage or access? | Cookie, localStorage, script, pixel |
| Is it first-party or third-party? | example.com vs advendor.com |
| What is the likely purpose? | Analytics, ads, functional, security |
| Did it run before consent? | Yes/no |
| Is there a plausible exemption? | Strictly necessary, user-requested service, security |
| Is it disclosed? | Vendor/purpose present in banner or policy |
Avoid overclaiming. If purpose is uncertain, mark it as unknown vendor/purpose requiring review, not automatically illegal.
Step 4: Click "Reject all"
After rejection:
- Capture storage again.
- Capture network activity for a fixed window.
- Reload the page.
- Capture storage and network again.
- Navigate to another page type.
- Compare with pre-consent state.
A strong reject test should answer:
| Question | Pass condition |
|---|---|
| Did analytics stop? | Yes, unless validly exempt |
| Did advertising stop? | Yes |
| Did pixels stop? | Yes |
| Did localStorage tracking stop? | Yes |
| Did third-party vendors disappear? | Non-essential vendors should disappear |
| Does rejection persist after reload? | Yes |
Step 5: Click "Accept all"
This creates the positive baseline.
Capture:
| Evidence | Purpose |
|---|---|
| New cookies | Shows what consent enables |
| New localStorage entries | Detects non-cookie tracking |
| New vendors | Builds inventory |
| New scripts | Identifies tag-manager activation |
| New network requests | Maps actual data flows |
| Event payloads | Detects analytics/ad event names |
The accept state helps distinguish technologies that are genuinely consent-gated from those that fire regardless of choice.
Step 6: Test granular choices
For example:
| User choice | Expected behavior |
|---|---|
| Analytics on, ads off | Analytics may run; adtech should stay blocked |
| Ads on, analytics off | Adtech may run; analytics should stay blocked |
| Personalization off | Personalization IDs should not be created |
| Necessary only | Only strictly necessary technologies should run |
Many CMPs fail here because categories are visually granular but technically bundled.
Step 7: Test withdrawal
After accepting all:
- Open privacy settings.
- Change to reject all.
- Save choice.
- Reload.
- Capture storage and network.
- Confirm non-essential tools no longer fire.
Withdrawal is important because GDPR consent must be withdrawable, and PECR compliance depends on ongoing control where consent is the basis for storage/access.
Step 8: Compare page types
One page is not enough.
Test at least:
| Page type | Why |
|---|---|
| Homepage | Often has marketing and analytics |
| Article or blog post | Often has ads, embeds, recommendation widgets |
| Product page | Often has conversion tracking |
| Checkout or lead form | Often has ad attribution and fraud tools |
| Login page | Often has security scripts |
| Video page | Often loads player SDKs and ad/video measurement |
| Search page | Often sends query and behavioral events |
A site can pass on the homepage and fail on video, checkout, or article pages.
9. What the report should show
A useful compliance report should be readable by legal, engineering, and marketing.
Executive summary
| Metric | Example |
|---|---|
| Overall result | Fail |
| Critical findings | 3 |
| Pre-consent vendors | 7 |
| Reject-state violations | 2 |
| Hidden vendors | 5 |
| localStorage tracking IDs | 4 |
| Tested states | Pre-consent, reject, accept, withdrawal |
Evidence table
| Finding | Evidence | Consent state | Risk |
|---|---|---|---|
| Advertising pixel fired before consent | Network request to third-party ad domain | Pre-consent | Critical |
| Analytics ID stored in localStorage after reject | localStorage key detected | Reject | High |
| Vendor missing from CMP list | Third-party script loaded | Pre-consent | Medium |
| Reject requires extra steps | Screenshot and click path | Banner UI | Medium |
Technical appendix
Include:
| Artifact | Purpose |
|---|---|
| Screenshots | Show what the user saw |
| HAR/network log | Show requests |
| Storage dump | Show cookies/storage |
| Consent timeline | Show sequence of events |
| Vendor map | Show third parties |
| Rule results | Show pass/fail logic |
| Hashes | Preserve evidence integrity |
For stronger evidence, generate timestamped reports and hash the raw audit artifacts.
10. How to avoid false positives
A scientific scanner must be careful.
Not every cookie is unlawful. Not every script is tracking. Not every third-party request is advertising. Some storage may be strictly necessary.
Examples of legitimate or lower-risk technologies:
| Technology | Possible reason |
|---|---|
| Session cookie | Login or cart functionality |
| CSRF token | Security |
| Load balancer cookie | Service delivery |
| Consent cookie | Stores the user's choice |
| Language preference | User-requested preference |
| Fraud prevention signal | May require separate legal analysis |
The scanner should flag uncertain cases as review needed rather than pretending legal certainty.
A good report separates:
| Label | Meaning |
|---|---|
| Confirmed violation | Strong evidence of non-exempt tracking before/after reject |
| Likely violation | Strong technical signal, purpose needs confirmation |
| Review needed | Unknown vendor or ambiguous purpose |
| Informational | Storage/access present but likely necessary |
| Pass | No relevant issue detected |
This distinction increases trust.
11. Remediation: how to fix common issues
Problem: Tags fire before consent
Fix:
- Move tags behind CMP consent checks.
- Configure tag-manager triggers by consent category.
- Block default firing until consent is known.
- Test in clean browser state.
- Retest reject and withdrawal.
Problem: localStorage identifiers appear before consent
Fix:
- Identify the script creating the key.
- Classify its purpose.
- Delay script execution until consent.
- Remove or rotate identifiers after withdrawal.
- Add storage checks to regression tests.
Problem: Vendor list is incomplete
Fix:
- Export all third-party domains from scans.
- Map domains to vendors.
- Update CMP/vendor disclosure.
- Remove unused vendors.
- Repeat scan after deployment.
Problem: Reject button exists but tracking continues
Fix:
- Validate CMP event callbacks.
- Check tag-manager consent mode.
- Confirm categories are not bundled.
- Test after reload and page navigation.
- Add automated reject-state monitoring.
Problem: Consent banner uses dark patterns
Fix:
- Make accept and reject equally accessible.
- Remove preselected optional choices.
- Use clear labels.
- Avoid misleading category names.
- Provide easy privacy settings access.
12. A simple scanner checklist
Use this checklist for each audited URL.
| Check | Pass/fail |
|---|---|
| Fresh browser scan completed | |
| Screenshot captured before consent | |
| Cookies captured before consent | |
| localStorage captured before consent | |
| sessionStorage captured before consent | |
| Network requests captured before consent | |
| Third-party scripts detected | |
| Pixels detected | |
| Link decoration inspected | |
| Reject all tested | |
| Accept all tested | |
| Withdrawal tested | |
| Granular categories tested | |
| Vendors mapped | |
| Purposes classified | |
| CMP disclosure compared with observed behavior | |
| Findings risk-rated | |
| Evidence archived |
Conclusion
A cookie banner is only the surface layer of compliance.
The real compliance question is whether non-exempt storage and access technologies are technically controlled across real user choices.
A modern scanner must therefore test:
- cookies,
- localStorage,
- sessionStorage,
- pixels,
- scripts,
- tags,
- link decoration,
- fingerprinting signals,
- network requests,
- consent state transitions.
The ICO's 2026 SAT guidance makes this broader audit model difficult to ignore. PECR is not limited to cookies, and neither should your compliance testing be.
The practical standard for 2026 is:
Do not trust the banner. Test the browser.
Sources
- ICO, Guidance on the use of storage and access technologies.
- ICO, About this guidance: what does it cover?
- ICO, What are storage and access technologies?
- EDPB, Guidelines 05/2020 on consent under Regulation 2016/679.
- EDPB, Guidelines 03/2022 on deceptive design patterns in social media platform interfaces.