# Persistent user tracking is possible using window.caches, by avoiding Brave Shields

Brave iOS CookieControl.js blocks cookies, localStorage and sessionStorage but not window.caches, letting sites persist a tracking ID across sessions despite Shields.

- Payout: hidden
- Severity: medium
- Program: Brave Software
- Found by: nishimunea
- Disclosed: 2023-06-22
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/1668815
- Library page: https://bugbountylibrary.com/r/h1%3A1668815
- Tags: area:mobile domain:browser domain:mobile impact:data-leak kind:bounty platform:hackerone sev:medium tech:ios technique:source-review vuln:info-disclosure

**Target:** WKWebView CookieControl.js user script
**Root cause:** CookieControl.js only clears cookie, localStorage and sessionStorage, omitting the Cache API (window.caches) introduced in iOS 15 WKWebView, which persists across sessions.
**Steps:**
1. Enable Brave Shields and block all cookies
2. Visit `https://csrf.jp/2022/caches.php`
3. Click 'Set Tracking ID' to store ID via `caches.open(...).put(...)`
4. Click 'Get Tracking ID' to read it back
5. Close browser, revisit page, click 'Get Tracking ID' — ID persists
**How found:** Code review of CookieControl.js against iOS 15's newly added window.caches API revealed the storage-clearing list was incomplete.
**Exploitation:** A site stores a unique identifier in the Cache API; because CookieControl.js never clears it, the ID survives browser restarts and cookie clearing, enabling cross-session tracking.
**Insight:** When auditing privacy/anti-tracking code, enumerate every client-side storage API (Cache API, IndexedDB, OPFS, service worker caches) — blockers often only handle the classic cookie/localStorage/sessionStorage trio.
