This is an old revision of the document!
Table of Contents
Provenance: privacy:browser_storage
Working notes behind browser_storage — every query with its population and denominator, the scripts and their unedited output, the hand audit and its residue, the quotes checked against the source papers, the external sources and how each was verified, and what could not be established. Corpus-level caveats that apply to every page on this site are on corpus and are not restated here.
1. What this page is backing
| Item | Value |
|---|---|
| Content page | browser_storage — new, created 2026-08-31 |
| Population and hand audit | scripts/bs_fold.mjs |
| Report script | scripts/report_browser_storage.mjs → scripts/report_browser_storage-output.txt |
| Quote check | scripts/bs_quotecheck.mjs (+ scripts/bs_pypdf_render.py) → scripts/bs_quotecheck-output.txt |
| Runnable code published on the page | bs_probe/storage_readout.mjs, bs_probe/partition_probe.mjs. The two <file javascript> blocks on the content page were extracted back out of the page into these files, and the files re-run, so the published text is byte-identical to the script that produced the quoted output (checked with difflib: 0 diff lines each) |
| Third probe, run but not published as code | bs_probe/clear_site_data_probe.mjs — its output table is on the page |
| Bibliography additions | scripts/bib_additions_browser_storage.bib — 15 entries |
| Data | data/extract/run1/extractions.jsonl — 5,859 papers, 7 venues, 2010–2026, plus data/fulltext/ |
| Written | 2026-08-31, against the corpus as extended on 2026-08-11 (commit 8a6b843) |
Create, not extend. Nothing on the wiki covered non-cookie client-side storage. cookies is about classifying cookies and mentions localStorage only inside a CookieBlock extraction snippet; stateful_stateless measures what a reset clears and is about the crawl's statefulness, not about the stores as measurement targets; fingerprinting is the stateless side. §9 records why this is a new page rather than a section of privacy:cookies.
2. Population: why it is not a schema query
No field in the extraction means “measured a non-cookie browser store”. Measured, not assumed:
| Signal | Papers it fires on | Of those, hand-audited to Tier A |
|---|---|---|
detection[] free text names a store | 20 | 15 |
classification[] free text names a store | 1 | 1 |
| full text, core score ≥ 3, hand-audited | 120 candidates | 43 |
classification.target has no storage value at all, and detection.phenomenon is a free-text field with roughly 20% run-to-run string stability. The schema route recovers 15 of the 43 Tier-A papers. So the population is built from full text and then hand-audited, with both steps published.
2.1 Step 1 — the mechanical probe
Occurrence counts over data/fulltext/<year>/<venue>/<slug>/paper.cols.txt, whitespace-collapsed before matching so that a PDF line break inside “local storage” does not silently drop the hit.
CORE localStorage /local\s?Storage|localstorage|\bDOM storage\b|\bWeb Storage\b/gi CORE sessionStorage /session\s?Storage|sessionstorage/gi CORE IndexedDB /Indexed\s?DB|indexeddb/gi CORE serviceWorker /service\s?workers?/gi CORE CacheAPI /Cache\s?Storage|caches\.(open|match|keys)|\bCache API\b/gi CORE WebSQL /Web\s?SQL/gi CONTEXT FlashLSO /Flash\s?cookies?|Local\s?Shared\s?Objects?|\bLSOs?\b/g CONTEXT evercookie /evercookies?|ever-cookies?|super\s?cookies?/gi CONTEXT respawn /respawn\w*|resurrect\w*/gi CONTEXT ETag /\bETags?\b|\bE-Tags?\b/g CONTEXT favicon /favicons?/gi
The core score is the sum of the six CORE counts; a paper is a candidate at core ≥ 3. CONTEXT probes are counted and reported but do not decide candidacy.
A regex that was thrown away. The first Flash probe was /flash\s?cookie|local shared object|\.sol\b|lso\b/i. lso\b matches inside the word “also”, so it fired on 5,819 of 5,859 papers. It was caught only because the number was absurd; a narrower probe would have failed silently in the same way. The published probe uses case-sensitive \bLSOs?\b.
Why the threshold is 3, and what it costs. Candidate counts at each threshold, for the three populations:
| core ≥ | whole corpus | ran a crawl (of 1,120) | measured the web platform (of 1,622) |
|---|---|---|---|
| 1 | 294 | 146 | 205 |
| 2 | 164 | 90 | 132 |
| 3 | 120 | 70 | 99 |
| 5 | 77 | 45 | 65 |
| 10 | 41 | 24 | 35 |
3 was picked before the audit, as the lowest threshold whose candidate list was small enough to read in full. It is published rather than tuned. A mention threshold is a candidate set, not a finding — the audit below is what turns it into one.
2.2 Step 2 — the hand audit, and its precision
Tiers were defined before reading:
- A — reports an empirical measurement of a non-cookie client-side store: its prevalence, its contents, identifiers in it, accesses to it, or whether it survives a clearing action.
- B — does not measure the store, but instruments, clears, blocks or models it as part of its method or threat model.
- out — not about a browser store (CPU, CDN and CI caches; native or Android filesystem “local storage”; WeChat mini-program storage), or the only hit is a related-work sentence.
| Tier | Papers | Share of 120 |
|---|---|---|
| A | 43 | 35.8% |
| B | 49 | 40.8% |
| out | 28 | 23.3% |
Precision of core ≥ 3 for “is about a browser store” (A or B): 76.7%. For “measured one” (A only): 35.8%.
The reading was of every storage-term sentence in the paper (produced by scripts/_bs_probe6.mjs, capped at six sentences per paper, ranked so that sentences containing measurement language come first), plus the surrounding section wherever the tier was not obvious from them. The full assignment table, one row per paper with a reason — all three tiers, not just Tier A — is the AUDIT constant in scripts/bs_fold.mjs and is printed in §4 by the report script, so it is readable here without repo access. report_browser_storage.mjs exits non-zero if a candidate has no audit entry or an audit entry has no candidate, so the table cannot drift out of sync with the probe.
2.3 Populations used on the page
| Name | Definition | N |
|---|---|---|
| whole corpus | every extracted paper | 5,859 |
| ran an automated web crawl | crawlConfig != null OR studyTypes includes automated-web-crawl | 1,120 |
| measured the web platform | platforms includes web | 1,622 |
| assessed a law | legal.length > 0 | 402 |
| assessed the GDPR or ePrivacy | of those, legal[].law matches GDPR or ePrivacy | 283 |
| crawled and stated a consent action | crawled AND crawlConfig.consentAction is not a sentinel | 349 |
A sentinel bug that survived the first draft. The consent population was originally written as consentAction !== “not-stated”, which gave 585. not-applicable is a sentinel too and 236 crawled papers carry it, so that filter counted a sentinel as an answer — exactly the failure the site's own rules warn about. The corrected filter uses isSentinel() from lib.mjs and gives 349, which is the figure OVERVIEW.md publishes for crawlConfig.consentAction. The mention share moved from 13.8% to 18.9%. Caught by the figures-versus-script reviewer, not by me; see §14.
4 of 5,859 papers have no paper.cols.txt and are excluded from every full-text figure. They are not excluded from the extraction-field figures, which is a small inconsistency and is stated here rather than papered over.
3. Running it
node scripts/report_browser_storage.mjs # plain text, ~40 s (reads 5,855 full texts) node scripts/report_browser_storage.mjs --wiki # DokuWiki tables node scripts/bs_quotecheck.mjs # 36 quotes against paper.cols.txt, pypdf fallback PLAYWRIGHT_BROWSERS_PATH=/workspace/.playwright node bs_probe/storage_readout.mjs PLAYWRIGHT_BROWSERS_PATH=/workspace/.playwright node bs_probe/partition_probe.mjs PLAYWRIGHT_BROWSERS_PATH=/workspace/.playwright node bs_probe/clear_site_data_probe.mjs
4. Unedited report output
- report_browser_storage-output.txt
# privacy:browser_storage — every figure with its denominator Corpus: 5859 papers, 7 venues (CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf, IEEE S&P), 2010-2026. 2025-2026 are provisional: CCS 2026 and IMC 2026 have not been held, and IEEE S&P / WWW 2026 are incompletely selected. Populations used below: crawled = 1120; web platform = 1622. ## Step 1 — the mechanical probe Whitespace-collapsed regex counts over data/fulltext/<year>/<venue>/<slug>/paper.cols.txt. CORE probes decide candidacy; CONTEXT probes are reported but do not, because they fire on a large non-storage literature (HTTP caching, phishing favicons, botnet resurrection). CORE localStorage /local\s?Storage|localstorage|\bDOM storage\b|\bWeb Storage\b/gi CORE sessionStorage /session\s?Storage|sessionstorage/gi CORE IndexedDB /Indexed\s?DB|indexeddb/gi CORE serviceWorker /service\s?workers?/gi CORE CacheAPI /Cache\s?Storage|caches\.(open|match|keys)|\bCache API\b/gi CORE WebSQL /Web\s?SQL/gi CONTEXT FlashLSO /Flash\s?cookies?|Local\s?Shared\s?Objects?|\bLSOs?\b/g CONTEXT evercookie /evercookies?|ever-cookies?|super\s?cookies?/gi CONTEXT respawn /respawn\w*|resurrect\w*/gi CONTEXT ETag /\bETags?\b|\bE-Tags?\b/g CONTEXT favicon /favicons?/gi 4 of 5859 papers have no paper.cols.txt. They stay inside every denominator N below and simply score 0 on the probe, so they can only depress a share, never inflate it. ## Mention rates — does the paper name the store at all? Population N names >=1 core store share core >= 3 share -------------------------- ---- -------------------- ----- --------- ----- ran an automated web crawl 1120 146 13.0% 70 6.3% measured the web platform 1622 205 12.6% 99 6.1% whole corpus 5859 294 5.0% 120 2.0% Per store, among the 1,120 papers that ran an automated web crawl. A paper is counted once. Store crawl papers naming it share of 1,120 -------------- ---------------------- -------------- localStorage 124 11.1% sessionStorage 38 3.4% IndexedDB 28 2.5% serviceWorker 30 2.7% CacheAPI 8 0.7% WebSQL 5 0.4% FlashLSO 34 3.0% evercookie 34 3.0% respawn 41 3.7% ETag 21 1.9% favicon 27 2.4% ## Step 2 — the hand audit, and the precision of step 1 Tier Papers Share of the 120 candidates ----------------------------------------- ------ --------------------------- A — measures a non-cookie browser store 43 35.8% B — instruments / clears / models it only 49 40.8% out — not about a browser store 28 23.3% candidates at core >= 3 120 100.0% Precision of the core >= 3 threshold for "is about a browser store" (A or B): 76.7%. Precision for the stricter "measures one" (A only): 35.8%. ## Tier A — the papers that measured a non-cookie store Venue Year Stores touched Why it is Tier A ------- ---- --------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- IEEE-SP 2010 Web Storage (local/session) earliest measured localStorage adoption in the corpus, 0.19% of sites USENIX 2010 Web Storage (local/session) extensions writing to localStorage under private browsing CCS 2013 Web Storage (local/session) flows into Web Storage sinks, i.e. persistent DOM-based XSS, on Alexa top 5k NDSS 2013 Web Storage (local/session) injection of attacker content into local storage on 84 measured hosts CCS 2014 Web Storage (local/session), IndexedDB, Flash LSO, HTTP / favicon cache IndexedDB as an evercookie vector, 20/100k sites; Flash-to-HTTP respawning IEEE-SP 2015 Web Storage (local/session), IndexedDB records third-party script accesses to localStorage and indexedDB USENIX 2016 Web Storage (local/session) longitudinal localStorage adoption from archived pages CCS 2018 Web Storage (local/session), Service worker / Cache Storage PWA/service-worker and offline-cache prevalence on Alexa top 100k IEEE-SP 2018 Web Storage (local/session) monitors survey-scam sites’ use of the Web Storage APIs USENIX 2018 Web Storage (local/session), Service worker / Cache Storage, Flash LSO, HTTP / favicon cache service workers and AppCache as third-party cookie-policy bypasses, counted NDSS 2019 Web Storage (local/session), IndexedDB, Service worker / Cache Storage, WebSQL prevalence of flows out of Local Storage into dangerous sinks, Alexa top 5k CCS 2020 Web Storage (local/session) audits local and session storage for leaked identifiers as well as cookies IMC 2020 Service worker / Cache Storage service workers as the push-ad delivery mechanism; blocker effectiveness against them NDSS 2020 Web Storage (local/session), Service worker / Cache Storage unique fingerprintable records in cookie and localStorage across top-10k IEEE-SP 2021 Web Storage (local/session), IndexedDB localStorage/sessionStorage/IndexedDB events are components of the measured signatures NDSS 2021 IndexedDB, Service worker / Cache Storage service-worker deployment and Cache Storage contents across Alexa top 1M NDSS 2021 Web Storage (local/session), Service worker / Cache Storage, HTTP / favicon cache favicon cache as a store that survives clearing browsing data PETS 2021 Web Storage (local/session), IndexedDB, Service worker / Cache Storage, Flash LSO HTTP cache as an identifier store; cacheable resources on Tranco 100k IMC 2022 Web Storage (local/session) records and compares first-party localStorage values across four crawler identities PETS 2022 Web Storage (local/session), IndexedDB, Flash LSO, HTTP / favicon cache respawning measurement; names localStorage and IndexedDB as respawn stores USENIX 2022 Web Storage (local/session), IndexedDB localStorage read/write counts are classifier features on a crawl WWW 2022 Web Storage (local/session), IndexedDB identifying tokens in third-party local storage under four partitioning policies CCS 2023 Web Storage (local/session) counts unique localStorage names alongside first-party cookie names on Tranco 20k IMC 2023 Web Storage (local/session) inspects the DOM storage area for identifiers on ad destination pages NDSS 2023 Web Storage (local/session), IndexedDB, Service worker / Cache Storage, WebSQL, Flash LSO, HTTP / favicon cache enumerates every storage vector across 126 browser versions and tests partitioning PETS 2023 Web Storage (local/session), Flash LSO, HTTP / favicon cache EME persistent sessions survived cookie and site-data deletion in two mobile browsers USENIX 2023 Web Storage (local/session), IndexedDB, Service worker / Cache Storage, HTTP / favicon cache documents which browsers partition DOM storage, and a channel that survives clearing it CCS 2024 Web Storage (local/session), Service worker / Cache Storage per-function localStorage access counts as the leading contextual feature CCS 2024 Web Storage (local/session), IndexedDB, Service worker / Cache Storage, HTTP / favicon cache extension traces in page-visible client-side stores as a fingerprinting surface IEEE-SP 2024 Web Storage (local/session) persistent client-side XSS tested by replacing keys in localStorage and sessionStorage PETS 2024 Web Storage (local/session) localStorage objects per site and per profile, alongside cookies USENIX 2024 Web Storage (local/session), Service worker / Cache Storage Web Storage, IndexedDB and chrome.storage are taint sinks in the extension audit USENIX 2024 Web Storage (local/session) captures identifier sharing through local storage as graph nodes WWW 2024 Web Storage (local/session), IndexedDB, WebSQL, HTTP / favicon cache monitors script accesses to LocalStorage, SessionStorage and IndexedDB WWW 2024 Web Storage (local/session), HTTP / favicon cache measures which Android browsers persist cache and cookies out of private mode PETS 2025 Web Storage (local/session) TC strings stored in localStorage vs cookies vs the API, and their disagreement USENIX 2025 Web Storage (local/session), IndexedDB, Service worker / Cache Storage chat histories persisted in IndexedDB inside extension service workers WWW 2025 Web Storage (local/session), IndexedDB, WebSQL Tranco top 10k; share of localStorage and IndexedDB accesses made by third-party scripts NDSS 2026 Web Storage (local/session) counts websites exposing SSO access tokens in local and session storage NDSS 2026 Web Storage (local/session), IndexedDB, Service worker / Cache Storage magic values written to localStorage/IndexedDB to detect site-isolation logic bugs PETS 2026 Web Storage (local/session), Service worker / Cache Storage share of wallets storing the account address in localStorage/cookies PETS 2026 Web Storage (local/session) collects local and session storage values alongside cookies to trace gclid PETS 2026 Web Storage (local/session) local storage as the identifier source in a comparison of tracking-detection techniques ## Tier B — instrumented, cleared, blocked or modelled it, but did not measure it Venue Year Stores touched Why it is Tier B ------- ---- -------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------- CCS 2011 Web Storage (local/session), HTTP / favicon cache partition includes localStorage; a defence, not a measurement IEEE-SP 2011 Web Storage (local/session) local storage is a capability in the extension model USENIX 2012 Web Storage (local/session) shims window.localStorage as part of a privilege-separation design CCS 2015 Web Storage (local/session), HTTP / favicon cache private-browsing design must cover HTML5 local storage NDSS 2015 Web Storage (local/session), Service worker / Cache Storage, Flash LSO, HTTP / favicon cache anti-tracking browser isolates cookie jars, cache stores and localStorage IEEE-SP 2016 Web Storage (local/session) use-of-storage is a low-entropy fingerprint attribute USENIX 2017 Web Storage (local/session), Service worker / Cache Storage local storage named as future SOP coverage CCS 2018 Web Storage (local/session) local storage is a taint sink for extension leakage IEEE-SP 2018 Web Storage (local/session) local storage is a rarely-changing fingerprint attribute USENIX 2018 Web Storage (local/session), WebSQL WebView-hosted web resources including storage WWW 2018 Web Storage (local/session) use of local/session storage is a boolean fingerprint attribute NDSS 2019 Web Storage (local/session), Service worker / Cache Storage service worker as the persistence mechanism of the attack; prevalence not measured WWW 2019 Web Storage (local/session), IndexedDB indexedDB/openDB among attributes deliberately not altered PETS 2020 Web Storage (local/session), Flash LSO, HTTP / favicon cache supercookies/ETag/localStorage named in background only PETS 2020 Web Storage (local/session), HTTP / favicon cache localStorage named in background as an identifier store CCS 2021 Web Storage (local/session), IndexedDB intercepts localStorage/sessionStorage accesses to build replacement resources CCS 2021 Service worker / Cache Storage service-worker XS-Leaks excluded from the test suite NDSS 2021 Web Storage (local/session) local storage is the per-origin asset the policy protects PETS 2021 Web Storage (local/session), IndexedDB, WebSQL crawl saves cookies, IndexedDB, LocalStorage, SessionStorage and WebSQL records PETS 2021 Web Storage (local/session) measures whether users understand the term "browser web storage", not the store USENIX 2021 Web Storage (local/session), Service worker / Cache Storage service-worker persistent MITM as a threat to the design USENIX 2021 Web Storage (local/session) web storage is an attacker-controlled input in the property graph CCS 2022 Web Storage (local/session), IndexedDB localStorage/sessionStorage/IndexedDB listed as in-browser message containers IEEE-SP 2022 Web Storage (local/session), Service worker / Cache Storage service workers in a formal web model NDSS 2022 Web Storage (local/session) client-side storage as an attacker-controllable taint source (Probe the Proto) PETS 2022 Web Storage (local/session), IndexedDB local storage named as client-side state, not measured separately USENIX 2022 Web Storage (local/session), IndexedDB clears cookies and local storage between fingerprinting trials IEEE-SP 2023 Web Storage (local/session), Service worker / Cache Storage formal model of service workers and the Cache API; no measurement IEEE-SP 2023 Web Storage (local/session), Service worker / Cache Storage cache storage and web storage among clobberable APIs; storage not measured USENIX 2023 Web Storage (local/session) sessionStorage holds the ballot reference in the audited client WWW 2023 Web Storage (local/session), Service worker / Cache Storage ServiceWorkerContainer.controller as a crawler-detection signal IEEE-SP 2024 Web Storage (local/session), Service worker / Cache Storage web storage values are program state in the vulnerability model IEEE-SP 2024 Service worker / Cache Storage custom tabs share service workers and caches with the browser IMC 2024 Service worker / Cache Storage disabling service workers zeroes fingerprint values NDSS 2024 Web Storage (local/session), Service worker / Cache Storage, HTTP / favicon cache service worker used for malware persistence in an ICS demonstration PETS 2024 IndexedDB, Service worker / Cache Storage their own MV3 extension uses a service worker and IndexedDB as apparatus PETS 2024 Web Storage (local/session), IndexedDB storage presence checks are fingerprinting sources in the tables WWW 2024 Web Storage (local/session) taint propagation through local storage is an engine feature IEEE-SP 2025 Web Storage (local/session) storage sinks in the gadget taxonomy IMC 2025 Web Storage (local/session), Service worker / Cache Storage storage-related attributes inside the fingerprint vector NDSS 2025 Web Storage (local/session) delta in local/session storage size is a breakage feature PETS 2025 Web Storage (local/session) FingerprintJS local-storage boolean among collected attributes PETS 2025 Web Storage (local/session), Service worker / Cache Storage WebView storage as the bridge between app and web identities USENIX 2025 Web Storage (local/session), IndexedDB, Service worker / Cache Storage interview study on which storage API extension developers pick USENIX 2025 Service worker / Cache Storage service workers are not captured by the recorder, so registration is disabled USENIX 2025 Web Storage (local/session) taint is stripped and restored around localStorage.setItem/getItem WWW 2025 Web Storage (local/session) compares taint engines on flows through localStorage NDSS 2026 Web Storage (local/session) WebView localStorage is a sensitive-API category in the taxonomy PETS 2026 Service worker / Cache Storage MV3 extension service workers as an ad-blocking constraint, not a web store ## Excluded — candidates at core >= 3 that are not about a browser store Venue Year Slug Why it is out ------- ---- ------------------------------------------------------------ ------------------------------------------------------------- IMC 2011 towards-understanding-modern-web-traffic "cache storage size" is proxy cache capacity CCS 2013 vetting-undesirable-behaviors-in-android-apps-with-permissio Android permissions; "local storage" is the device filesystem NDSS 2015 a-first-look-at-the-usability-of-bitcoin-key-management "local storage" means the device filesystem IEEE-SP 2016 cache-storage-channels-alias-driven-attacks-and-verified-cou CPU cache storage channels USENIX 2017 measuring-https-adoption-on-the-web service workers cited only as an HTTPS-only feature WWW 2019 snapshot-based-loading-acceleration-of-web-apps-with-nondete page-load acceleration; storage is a source of nondeterminism CCS 2020 youve-changed-detecting-malicious-browser-extensions-through no storage-bearing sentence survived the audit read IEEE-SP 2020 automatic-uncovering-of-hidden-behaviors-from-input-validati mobile app input validation CCS 2021 this-sneaky-piggy-went-to-the-android-ad-market-misusing-mob Android sensors IEEE-SP 2021 reading-between-the-lines-an-extensive-evaluation-of-the-sec no browser storage measurement CCS 2023 when-free-tier-becomes-free-to-enter-a-non-intrusive-way-to- cloud service capacity IEEE-SP 2023 fashion-faux-pas-implicit-stylistic-fingerprints-for-bypassi single passing mention of IndexedDB visibility NDSS 2023 stealthyimu-stealing-permission-protected-private-informatio smartphone sensors USENIX 2023 sneaky-spy-devices-and-defective-detectors-the-ecosystem-of- "local storage" is an SD card USENIX 2023 credit-karma-understanding-security-implications-of-exposed- cloud services CCS 2024 minicat-understanding-and-detecting-cross-page-request-forge WeChat mini-program local storage, not a browser store CCS 2024 unmasking-the-security-and-usability-of-password-masking sessionStorage is the authors’ own study apparatus IEEE-SP 2024 more-haste-less-speed-cache-related-security-threats-in-cont CI build caches PETS 2024 generational-differences-in-understandings-of-privacy-termin terminology survey, no storage measurement USENIX 2024 rise-of-inspectron-automated-black-box-auditing-of-cross-pla Electron desktop apps USENIX 2024 resolverfuzz-automated-discovery-of-dns-resolver-vulnerabili DNS resolvers USENIX 2024 sync-sync-a-covert-channel-built-on-fsync-with-storage filesystem fsync covert channel CCS 2025 ghostcache-timer-and-counter-free-cache-attacks-exploiting-w CPU cache, not a browser store IEEE-SP 2025 security-analysis-of-master-password-protected-password-mana "local storage" means files on disk NDSS 2025 a-comprehensive-memory-safety-analysis-of-bootloaders bootloaders NDSS 2026 phantommotion-laser-based-motion-injection-attacks-on-wirele physical attacks on cameras NDSS 2026 mvpnalyzer-an-investigative-framework-for-auditing-the-secur mobile VPN apps USENIX 2026 end-to-end-encrypted-collaborative-documents E2EE document protocol ## Tier A over time Bucket Papers in corpus Tier A share Tier A or B share ----------------------- ---------------- ------ ----- ----------- ----- 2010-2013 511 4 0.8% 7 1.4% 2014-2017 769 3 0.4% 7 0.9% 2018-2021 1439 11 0.8% 26 1.8% 2022-2024 1955 17 0.9% 33 1.7% 2025-2026 (provisional) 1185 8 0.7% 19 1.6% Per year, so the provisional years are visible rather than folded away. Year Papers names >=1 core store share Tier A ---- ------ -------------------- ----- ------ 2010 119 3 2.5% 2 2011 116 6 5.2% 0 2012 151 6 4.0% 0 2013 125 6 4.8% 2 2014 166 8 4.8% 1 2015 190 14 7.4% 1 2016 182 8 4.4% 1 2017 231 9 3.9% 0 2018 254 16 6.3% 3 2019 402 15 3.7% 1 2020 404 15 3.7% 3 2021 379 24 6.3% 4 2022 546 22 4.0% 4 2023 719 32 4.5% 5 2024 690 46 6.7% 8 2025 770 42 5.5% 3 2026 415 22 5.3% 5 ## Which store, among Tier A and Tier B papers Store family Papers (of 92 in tiers A+B) share ------------------------------ --------------------------- ----- Web Storage (local/session) 84 91.3% Service worker / Cache Storage 35 38.0% IndexedDB 25 27.2% HTTP / favicon cache 16 17.4% Flash LSO 8 8.7% WebSQL 6 6.5% Multi-valued: a paper touching localStorage and IndexedDB is counted in both rows, so the column does not sum to 92. ## Residue — what the threshold missed, printed in full Papers at core = 1 or 2 (below the candidacy threshold) that name a first-class storage API. These were NOT audited. They are printed so the part the threshold dropped stays visible. 174 papers. Of those, 106 measured the web platform. The web-platform ones, which are where an in-scope paper would hide: CCS/2010/blade-an-attack-agnostic-approach-for-preventing-drive-by-malware-infections [localStorage:2] CCS/2011/fortifying-web-based-applications-automatically [localStorage:2] IEEE-SP/2011/i-still-know-what-you-visited-last-summer-leaking-browsing-history-via-user-inte [localStorage:2] CCS/2012/operating-system-framed-in-case-of-mistaken-identity-measuring-the-success-of-we [localStorage:1] CCS/2012/the-devil-is-in-the-implementation-details-an-empirical-analysis-of-oauth-sso-sy [localStorage:1] IEEE-SP/2012/third-party-web-tracking-policy-and-technology [localStorage:2] IEEE-SP/2012/memento-learning-secrets-from-process-footprints [localStorage:1] WWW/2013/rethinking-the-web-as-a-personal-archive [localStorage:1] USENIX/2013/on-the-security-of-picture-gesture-authentication [localStorage:1] CCS/2014/a-critical-evaluation-of-website-fingerprinting-attacks [sessionStorage:1] USENIX/2014/the-emperor-s-new-password-manager-security-analysis-of-web-based-password-manag [localStorage:1] USENIX/2014/precise-client-side-protection-against-dom-based-cross-site-scripting [localStorage:2] USENIX/2014/privee-an-architecture-for-automatically-analyzing-web-privacy-policies [localStorage:2] CCS/2015/from-facepalm-to-brain-bender-exploring-client-side-cross-site-scripting [localStorage:1] USENIX/2015/cookies-lack-integrity-real-world-implications [localStorage:1 sessionStorage:1] WWW/2015/automatic-detection-of-information-leakage-vulnerabilities-in-browser-extensions [localStorage:2] WWW/2015/network-based-origin-confusion-attacks-against-https-virtual-hosting [localStorage:1] CCS/2015/the-sicilian-defense-signature-based-whitelisting-of-web-javascript [localStorage:1] IMC/2015/affiliate-crookies-characterizing-affiliate-marketing-abuse [localStorage:1] CCS/2016/online-tracking-a-1-million-site-measurement-and-analysis [localStorage:2] IMC/2016/browser-feature-usage-on-the-modern-web [localStorage:1] USENIX/2016/the-ever-changing-labyrinth-a-large-scale-analysis-of-wildcard-dns-powered-black [localStorage:1] USENIX/2016/tracing-information-flows-between-ad-exchanges-using-retargeted-ads [localStorage:1] IEEE-SP/2016/you-get-where-youre-looking-for-the-impact-of-information-sources-on-code-securi [localStorage:1] IMC/2017/if-you-are-not-paying-for-it-you-are-the-product-how-much-do-advertisers-pay-to [localStorage:1] NDSS/2017/thou-shalt-not-depend-on-me-analysing-the-use-of-outdated-javascript-libraries-o [localStorage:2] PETS/2017/cross-device-tracking-measurement-and-disclosures [localStorage:1] PETS/2017/detecting-anti-ad-blockers-in-the-wild [localStorage:2] USENIX/2017/a-privacy-analysis-of-cross-device-tracking [localStorage:1 sessionStorage:1] WWW/2017/de-anonymizing-web-browsing-data-with-social-networks [localStorage:1] CCS/2018/the-webs-sixth-sense-a-study-of-scripts-accessing-smartphone-sensors [localStorage:1 sessionStorage:1] IMC/2018/a-long-way-to-the-top-significance-structure-and-stability-of-internet-top-lists [localStorage:1] IMC/2018/an-empirical-study-of-the-i2p-anonymity-network-and-its-censorship-resistance [localStorage:1] PETS/2018/i-never-signed-up-for-this-privacy-implications-of-email-tracking [localStorage:1] USENIX/2018/fp-scanner-the-privacy-implications-of-browser-fingerprint-inconsistencies [localStorage:1] USENIX/2018/wpse-fortifying-web-protocols-via-browser-side-security-monitoring [localStorage:1] WWW/2018/adbudgetkiller-online-advertising-budget-draining-attack [localStorage:1] CCS/2019/oh-the-places-youve-been-user-reactions-to-longitudinal-transparency-about-third [IndexedDB:1] IEEE-SP/2019/empoweb-empowering-web-applications-with-browser-extensions [localStorage:1] IEEE-SP/2019/postcards-from-the-post-http-world-amplification-of-https-vulnerabilities-in-the [localStorage:1] NDSS/2019/dns-cache-based-user-tracking [CacheAPI:2] NDSS/2019/javascript-template-attacks-automatically-inferring-host-information-for-targeted-exploits [serviceWorker:2] NDSS/2019/statistical-privacy-for-streaming-traffic [localStorage:1] USENIX/2019/all-your-clicks-belong-to-me-investigating-click-interception-on-the-web [localStorage:1] USENIX/2019/devils-in-the-guidance-predicting-logic-vulnerabilities-in-payment-syndication-s [localStorage:1] USENIX/2019/protecting-accounts-from-credential-stuffing-with-password-breach-alerting [localStorage:1] IEEE-SP/2020/meddling-middlemen-empirical-analysis-of-the-risks-of-data-saving-mobile-browser [localStorage:1] IMC/2020/hiding-in-plain-site-detecting-javascript-obfuscation-through-concealed-browser [serviceWorker:2] NDSS/2020/fuse-finding-file-upload-bugs-via-penetration-testing [localStorage:1] WWW/2020/beyond-the-front-page-measuring-third-party-dynamics-in-the-field [localStorage:1] WWW/2020/dont-count-me-out-on-the-relevance-of-ip-address-in-the-tracking-ecosystem [localStorage:1 IndexedDB:1] IEEE-SP/2021/fingerprinting-the-fingerprinters-learning-to-detect-browser-fingerprinting-beha [localStorage:1 IndexedDB:1] PETS/2021/the-cname-of-the-game-large-scale-analysis-of-dns-based-tracking-evasion [localStorage:1] PETS/2021/a-calculus-of-tracking-theory-and-practice [localStorage:1] WWW/2021/cookie-swap-party-abusing-first-party-cookies-for-web-tracking [localStorage:1] CCS/2022/do-opt-outs-really-opt-me-out [localStorage:1 IndexedDB:1] IMC/2022/respect-the-origin-a-best-case-evaluation-of-connection-coalescing-in-the-wild [localStorage:1] PETS/2022/fp-radar-longitudinal-measurement-and-early-detection-of-browser-fingerprinting [localStorage:1 IndexedDB:1] USENIX/2022/automating-cookie-consent-and-gdpr-violation-detection [localStorage:1] USENIX/2022/leaky-forms-a-study-of-email-and-password-exfiltration-before-form-submission [localStorage:1 IndexedDB:1] USENIX/2022/practical-data-access-minimization-in-trigger-action-platforms [localStorage:1] USENIX/2022/targeted-deanonymization-via-the-cache-side-channel-attacks-and-defenses [serviceWorker:1] USENIX/2022/the-dangers-of-human-touch-fingerprinting-browser-extensions-through-user-action [serviceWorker:1] NDSS/2023/auto-draft-336 [localStorage:2] NDSS/2023/rescan-a-middleware-framework-for-realistic-and-robust-black-box-web-application-scanning [sessionStorage:1 serviceWorker:1] PETS/2023/blocking-javascript-without-breaking-the-web-an-empirical-investigation [localStorage:1] CCS/2023/understanding-and-detecting-abused-image-hosting-modules-as-malicious-services [localStorage:1] PETS/2023/senrev-measurement-of-personal-information-disclosure-in-online-health-communiti [localStorage:1] IMC/2023/thou-shalt-not-reject-analyzing-accept-or-pay-cookie-banners-on-the-web [localStorage:1] USENIX/2023/automated-cookie-notice-analysis-and-enforcement [localStorage:1] USENIX/2023/device-tracking-via-linux-s-new-tcp-source-port-selection-algorithm [localStorage:1] USENIX/2023/extending-a-hand-to-attackers-browser-privilege-escalation-attacks-via-extension [serviceWorker:1] USENIX/2023/is-your-wallet-snitching-on-you-an-analysis-on-the-privacy-implications-of-web3 [IndexedDB:1] USENIX/2023/isolated-and-exhausted-attacking-operating-systems-via-site-isolation-in-the-bro [localStorage:1] IEEE-SP/2023/mega-malleable-encryption-goes-awry [localStorage:1] IEEE-SP/2023/detection-of-inconsistencies-in-privacy-practices-of-browser-extensions [serviceWorker:1] IEEE-SP/2023/the-leaky-web-automated-discovery-of-cross-site-information-leaks-in-browsers-an [serviceWorker:1] IMC/2024/a-first-look-at-related-website-sets [localStorage:1] CCS/2024/the-privacy-utility-trade-off-in-the-topics-api [localStorage:1] PETS/2024/generalizable-active-privacy-choice-designing-a-graphical-user-interface-for-glo [localStorage:1 sessionStorage:1] PETS/2024/johnny-still-cant-opt-out-assessing-the-iab-ccpa-compliance-framework [localStorage:1] PETS/2024/website-data-transparency-in-the-browser [IndexedDB:2] USENIX/2024/did-they-f-ing-consent-to-that-safer-digital-intimacy-via-proactive-protection-a [localStorage:2] USENIX/2024/fv8-a-forced-execution-javascript-engine-for-detecting-evasive-techniques [localStorage:1 serviceWorker:1] USENIX/2024/dancer-in-the-dark-synthesizing-and-evaluating-polyglots-for-blind-cross-site-sc [localStorage:1] USENIX/2024/trust-me-if-you-can-how-usable-is-trusted-types-in-practice [localStorage:1] WWW/2024/adflush-a-real-world-deployable-machine-learning-solution-for-effective-advertis [serviceWorker:1] WWW/2024/a-study-of-gdpr-compliance-under-the-transparency-and-consent-framework [localStorage:1] WWW/2024/experimental-security-analysis-of-sensitive-data-access-by-browser-extensions [serviceWorker:1] USENIX/2024/web-platform-threats-automated-detection-of-web-security-issues-with-wpt [IndexedDB:1 serviceWorker:1] IEEE-SP/2024/targeted-and-troublesome-tracking-and-advertising-on-childrens-websites [localStorage:1] IEEE-SP/2025/racedb-detecting-request-race-vulnerabilities-in-database-backed-web-application [CacheAPI:2] IEEE-SP/2025/only-as-strong-as-the-weakest-link-on-the-security-of-brokered-single-sign-on-on [localStorage:1] IMC/2025/toward-better-efficiency-vs-fidelity-tradeoffs-in-web-archives [localStorage:1] PETS/2025/rethinking-fingerprinting-an-assessment-of-behavior-based-methods-at-scale-and-i [localStorage:1] USENIX/2025/double-edged-shield-on-the-fingerprintability-of-customized-ad-blockers [serviceWorker:1] WWW/2025/digital-disparities-a-comparative-web-measurement-study-across-economic-boundari [serviceWorker:1] USENIX/2025/navigating-cookie-consent-violations-across-the-globe [localStorage:1] NDSS/2025/secret-spilling-drive-leaking-user-behavior-through-ssd-contention [localStorage:1] USENIX/2025/a-framework-for-abusability-analysis-the-case-of-passkeys-in-interpersonal-threa [localStorage:2] PETS/2025/lost-in-translation-exploring-the-risks-of-web-to-cross-platform-application-mig [localStorage:1 serviceWorker:1] PETS/2025/understanding-regional-filter-lists-efficacy-and-impact [localStorage:1] PETS/2025/sheeps-clothing-wolfish-intent-automated-detection-and-evaluation-of-problematic [localStorage:2] PETS/2026/websp-eval-evaluating-web-agents-on-website-security-and-privacy-tasks [serviceWorker:2] USENIX/2026/the-state-of-passkeys-studying-the-adoption-and-security-of-passkeys-on-the-web [localStorage:1] USENIX/2026/bridges-to-self-silent-web-to-app-tracking-on-mobile-via-localhost [localStorage:1] ## Reporting gap — what a crawl paper says about clearing state Among the 1,120 papers that ran a crawl Papers Share ------------------------------------------------------------------- ------ -------------- text contains a state-clearing / fresh-profile phrase 83 7.4% ... and names at least one non-cookie store anywhere in the paper 29 34.9% of those ... and never names one 54 65.1% of those This is a MENTION test, not a claim that those papers failed to clear the store. It says only that a reader cannot tell from the paper. First twelve of the second group: IMC/2010/understanding-latent-interactions-in-online-social-networks CCS/2011/automated-black-box-detection-of-side-channel-vulnerabilities-in-web-application CCS/2012/knowing-your-enemy-understanding-and-detecting-malicious-web-advertising CCS/2012/touching-from-a-distance-website-fingerprinting-attacks-and-defenses CCS/2014/a-systematic-approach-to-developing-and-evaluating-website-fingerprinting-defens CCS/2014/your-online-interests-pwned-a-pollution-attack-against-targeted-advertising IEEE-SP/2014/stealing-webpages-rendered-on-your-browser-by-exploiting-gpu-vulnerabilities IMC/2015/location-location-location-the-impact-of-geolocation-on-web-search-personalizati IMC/2015/measurement-and-analysis-of-traffic-exchange-services WWW/2015/privaricator-deceiving-fingerprinters-with-little-white-lies CCS/2017/hiding-in-plain-sight-a-longitudinal-study-of-combosquatting-abuse IMC/2018/impact-of-device-performance-on-mobile-internet-qoe ## Overlap with the compliance literature Population N names >=1 core store share Tier A ------------------------------------------- --- -------------------- ----- ------ assessed a law 402 35 8.7% 4 assessed the GDPR or the ePrivacy Directive 283 27 9.5% 3 crawled and stated a consent action 349 66 18.9% 22 Again a MENTION test. It does not say those papers measured only cookies, only that the word never appears. Tier A is the hand-audited count that did measure a non-cookie store. ## Published figures, and where each comes from Paper detection.phenomenon Paper's own denominator detection.prevalence ------------ --------------------------------------------- ------------------------------------------ --------------------------------------------------------------------------------------------------------------------------- WWW 2025 Third-party localStorage accesses Tranco top 10,000 90.98% of all localstorage accesses WWW 2025 Third-party IndexedDB accesses Tranco top 10,000 72.49% of all IndexedDB accesses WWW 2025 Third-party cookie accesses Tranco top 10,000 89.84% of all cookie accesses NDSS 2021 service-worker deployment Alexa top 1M 30,229 sites installed service workers NDSS 2021 service-worker functionality the 30,229 sites with a service worker 9,446 websites implemented caching; 9,900 implemented Fetch; 25,457 used Web Push CCS 2018 PWA deployment Alexa top 100,000 4,163 PWA websites CCS 2018 Offline cache usage the 4,163 PWA sites 513 (12.3%) use offline cache CCS 2014 IndexedDB evercookie Alexa top 100,000 20 out of 100,000 sites used IndexedDB; one matched a Flash cookie IEEE-SP 2010 browser feature usage 89,222 analysed sites of Alexa top 100,000 89,222 sites analyzed; feature-specific percentages reported in Table IV NDSS 2019 persistent client-side XSS Alexa top 5,000 more than 8% exhibit exploitable flows from client-side storage to a dangerous sink NDSS 2020 website fingerprintability reachable sites of Alexa top-10K 39.1% (2,541 of 6,500 reachable websites) PETS 2024 Local-storage usage Tranco crawl profiles 122k objects identified on average across profiles USENIX 2018 extension bypasses 46 extension policies 26 policies bypassed with AppCache and 20 through service workers IMC 2020 ad-blocker effectiveness the tested ad blockers All tested blockers blocked 0 Service Worker scripts NDSS 2021 valid favicon resources Alexa top 10K eTLD+1 domains 94% of domains have valid favicon resources PETS 2021 Cache-header vulnerable resources Tranco top 100,000 91,755 resources on 12,970 websites PETS 2022 cookie respawning with browser fingerprinting Alexa top 30,000 1,150 of 30,000 websites (3.83%) NDSS 2023 Browser mechanisms usable as tracking vectors 126 browser versions, 7 browsers 21 mechanisms across 126 versions of seven browsers; all latest tested versions were vulnerable to at least one technique PETS 2023 Persistent-session cookie-like storage tested browser configurations Mobile Opera and Samsung Internet retained sessions after cookie and site-data deletion. WWW 2024 Private web-cache storage 49 evaluated Android browser apps 15 browsers, 30.6% USENIX 2025 context retention 9 generative-AI assistant extensions ChatGPT for Google preserved context across multiple websites; seven assistants isolated contexts across sessions and tabs. PETS 2025 consent-storage inconsistency websites with a detected consent record 5 TCF cookie/API, 3 TCF localStorage/API, and 4 OneTrust mismatches CCS 2023 First-party tracking cookies Tranco top 20K 89.86% of the 20K websites WWW 2022 Local-storage tracking potential Tranco top 1,000 (repeat crawls) PITS were much less frequent than PICFs, but about equally common under site-keyed and permissive policies USENIX 2010 Chrome extension persistence top 100 Chrome extensions 71/100 used localStorage; 5 included native-code plugins; 4 used Google Analytics. USENIX 2016 HTML5 LocalStorage use archived pages, 1996-2016 use rises rapidly since its introduction in 2009 PETS 2026 third-party tracking 30 Ethereum dApps 19 of 30 dApps (63.3%) contacted at least one; 14 contacted three or more. Every row above is the extraction's verbatim `prevalence` string. The denominator column is read from the paper, not from the extraction, because `metric` names the unit and not the population. ## The stores nobody has measured Origin Private File System: 2 papers mention it USENIX/2023/r-b-ransomware-over-modern-web-browsers NDSS/2026/are-your-sites-truly-isolated-automatically-detecting-logic-bugs-in-site-isolation-implementations Storage Bucket API: 14 papers mention it PETS/2015/blocking-resistant-communication-through-domain-fronting CCS/2021/out-of-sight-out-of-mind-detecting-orphaned-web-pages-at-internet-scale IMC/2022/measuring-uid-smuggling-in-the-wild IMC/2022/respect-the-origin-a-best-case-evaluation-of-connection-coalescing-in-the-wild PETS/2022/we-may-share-the-number-of-diaper-changes-a-privacy-and-security-analysis-of-mob WWW/2022/measuring-the-privacy-vs-compatibility-trade-off-in-preventing-third-party-state IMC/2023/cloud-watching-understanding-attacks-against-cloud-hosted-services NDSS/2024/graphguard-detecting-and-counteracting-training-data-misuse-in-graph-neural-networks NDSS/2024/breakspf-how-shared-infrastructures-magnify-spf-vulnerabilities-across-the-internet PETS/2025/uncovering-the-app-cloud-access-risks-under-recommended-iam-security-practices IEEE-SP/2025/the-file-that-contained-the-keys-has-been-removed-an-empirical-analysis-of-secre NDSS/2026/better-safe-than-sorry-uncovering-the-insecure-resource-management-in-app-in-app-cloud-services IMC/2025/dive-into-the-cloud-unveiling-the-ab-usage-of-serverless-cloud-function-in-the-w PETS/2026/dead-domains-living-data-a-privacy-risk-analysis-of-domain-lifecycle-in-android File System API (legacy): 11 papers mention it CCS/2012/blacksheep-detecting-compromised-hosts-in-homogeneous-crowds USENIX/2018/a-sense-of-time-for-javascript-and-node-js-first-class-timeouts-as-a-cure-for-ev WWW/2019/snapshot-based-loading-acceleration-of-web-apps-with-nondeterministic-javascript NDSS/2021/towards-measuring-supply-chain-attacks-on-package-managers-for-interpreted-languages USENIX/2023/r-b-ransomware-over-modern-web-browsers NDSS/2023/navigating-murky-waters-automated-browser-feature-testing-for-uncovering-tracking-vectors USENIX/2023/bunnyhop-exploiting-the-instruction-prefetcher USENIX/2024/ihunter-hunting-privacy-violations-at-scale-in-the-software-supply-chain-on-ios NDSS/2025/welcome-to-jurassic-park-a-comprehensive-study-of-security-risks-in-deno-and-its-ecosystem CCS/2025/windows-plays-jenga-uncovering-design-weaknesses-in-windows-file-system-security WWW/2026/bridging-expert-reasoning-and-llm-detection-a-knowledge-driven-framework-for-mal Read the lists, not the counts. "Storage bucket" fires on cloud object storage (S3/GCS buckets) far more often than on the web API of that name, and no paper in any of these lists measures the store on the live web: the mentions are threat-model inventories, a browser-fuzzing target list, and cloud infrastructure. ## Sanity: what the extraction schema alone would have given Signal Papers Of them, Tier A ---------------------------------------- ------ --------------- detection[] free text names a store 20 15 classification[] free text names a store 1 1 full-text core >= 3, hand-audited to A 43 43 The schema route recovers a minority of the Tier-A set, which is why this page is built from full text.
5. The residue the threshold dropped
174 papers score core 1 or 2 and were not audited. 106 of them measured the web platform, which is where an in-scope paper would hide. The complete list is in §4 above, under Residue — what the threshold missed, printed in full.
Two of them were checked by hand because a reader would expect them to be in scope:
| Paper | Core score | Checked | Verdict |
|---|---|---|---|
CCS/2016/online-tracking-a-1-million-site-measurement-and-analysis (OpenWPM, Englehardt and Narayanan) | localStorage:2 | read both hits | Not Tier A. One hit is related work (“Ayenson et al. showed how sites were using cache E-Tags and HTML5 localStorage for the same purpose”), the other describes what a persistent profile carries (“Measurements can keep state, such as cookies and localStorage”). No storage measurement |
IMC/2016/browser-feature-usage-on-the-modern-web | localStorage:1 | read the hit and its table | Not Tier A extractable. “HTML: Web Storage H-WS” appears in a large feature-abbreviation table; the same page's .cols rendering also assigns H-WS to “HTML: Web Sockets”, so the reading order is unreliable and no per-feature figure can be lifted safely. Worth a human reading the PDF if someone wants a 2016 Web Storage adoption number |
Two more known false negatives of the population, both by platform rather than by score. WWW/2024/from-promises-to-practice… (Android private browsing) has platforms extracted as mobile, not web, and crawlConfig null, so it is absent from the crawled and web-platform mention rates while being Tier A — it is in the audit because candidacy uses core score, not platform. NDSS/2026/cross-boundary-mobile-tracking… and PETS/2025/tracking-without-borders… are WebView storage papers, audited to Tier B, and likewise invisible to the web-platform rate. Any mention-rate figure on the page is therefore a lower bound on WebView and mobile-browser work.
6. Figures on the page, and where each one comes from
Three kinds of number appear on the content page and they have three different audit trails.
6.1 From the report script
Every corpus count — the mention rates, the per-store table, the tier counts, the four-year buckets, the compliance overlap — is produced by report_browser_storage.mjs and appears in §4. scripts/check_page_numbers.mjs was run against the page and the report output; it accounted for all of them.
6.2 From a source paper
One extraction denominator was wrong and had to be corrected from the paper. The detection tuple for [1Munir, Shaoor; Siby, Sandra; Iqbal, Umar; Englehardt, Steven; Shafiq, Zubair; Troncoso, Carmela (2023): "CookieGraph: Understanding and Detecting First-Party Tracking Cookies", pp. 3490–3504. Association for Computing Machinery, New York, NY, USA. (DOI) (Link)] reads 89.86% of the 20K websites. The paper's crawl is 20,000 sites, but it is a stratified sample of the Tranco top million — 1,000 top sites, 9,000 uniformly sampled from ranks 1K–100K and 10,000 from 100K–1M — not the Tranco top 20,000; and the 89.86% figure itself comes from a separate deployment on a 20% sample of the top million, which is why the paper's own abstract says “89.86% of the top-million websites”. The first draft of the content page carried “Tranco top 20,000” for the 217,444 / 99,682 / 13,571 row, which is the 20K stratified crawl and is now described as such. The 89.86% figure is not quoted on this page at all. cookies quotes it with the paper's “top-million” phrasing and is consistent with the source; the apparent conflict between the two pages was an artefact of the extraction string, not of either page.
The 23 figures the number guard flagged as unaccounted after the final run are all of this kind or the next — browser and library version numbers, figures read out of a source paper, and one piece of arithmetic on report output. Nothing script-derived was unaccounted. Note what the guard cannot do: it traces digits, so it says nothing about whether a quoted phrase is real or whether a figure is attached to the right sentence. §7 is the check for the first and the reviewers in §14 for the second. Each is either quote-checked in §7 or, where the figure is a table cell rather than a sentence, read out of the paper directly. Three that were read out of tables rather than prose, with the exact table:
| Figure | Source | Verified against |
|---|---|---|
| 4,163 PWAs; 513 (12.3%) using an offline cache | [2Lee, Jiyeon; Kim, Hayeon; Park, Junghwan; Shin, Insik; Son, Sooel (2018): "Pride and Prejudice in Progressive Web Apps: Abusing Native App-like Features in Web Applications", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] | Table 1, “PWA statistics for the Alexa top 100,000 sites”: Cache 513 (12.3%) … Total 4,163 (100%) |
| 187 (36.5%) of cache-using PWAs identifiable | [2Lee, Jiyeon; Kim, Hayeon; Park, Junghwan; Shin, Insik; Son, Sooel (2018): "Pride and Prejudice in Progressive Web Apps: Abusing Native App-like Features in Web Applications", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] | Table 5, Vulnerable 187 (36.5%) … Total 513 (100%) — note the denominator is the 513 cache-using PWAs, not the 4,163 |
| 30,229 sites with a service worker; 9,446 caching; 25,457 Web Push | [3Karami, Soroush; Ilia, Panagiotis; Polakis, Jason (2021): "Awakening the Web's Sleeper Agents: Misusing Service Workers for Privacy Leakage", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] | Table I, “Service worker functionality in the Alexa top 1M”, the Landing page w/ Additional pages column |
| 15 (30.6%) and 16 (32.7%) of Android browsers | [4Liu, Xiaoyin; Li, Wenzhi; Hou, Qinsheng; Yang, Shishuai; Ying, Lingyun; Diao, Wenrui; Li, Yanan; Guo, Shanqing; Duan, Haixin (2024): "From Promises to Practice: Evaluating the Private Browsing Modes of Android Browser Apps", in: Proceedings of the ACM Web Conference. (DOI)] | denominator is the paper's 49 evaluated apps; 15/49 = 30.6% and 16/49 = 32.7% were recomputed to confirm which of the paper's two populations (60 and 49) the shares are of |
One page figure is arithmetic on report output and belongs to nobody else: “996 papers” in §Methodology and limitations is 1,120 − 124, and is stated on the page as the complement it is.
6.3 Measured in this run
The readout table, the partitioning result and the Clear-Site-Data table are new measurements, not literature. Their scripts are published on the page (the first two) or in the workdir (the third), and their unedited output is in §8. Version numbers: Playwright 1.62.1, Puppeteer 25.9.0, Chromium 151.0.7922.34, Linux. Chrome stable was 152.0.7977.64 on the day of the run, so Playwright's bundled Chromium is one major version behind; none of the three results depends on a 152-only behaviour, but the gap is the reason to re-run rather than to cite these tables in 2027.
7. Quotes checked against the source papers
35 quotes, all located. (36 checks were run in the first pass; one was the same [2Lee, Jiyeon; Kim, Hayeon; Park, Junghwan; Shin, Insik; Son, Sooel (2018): "Pride and Prejudice in Progressive Web Apps: Abusing Native App-like Features in Web Applications", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] sentence listed twice, found by the generic reviewer and de-duplicated.) bs_quotecheck.mjs collapses whitespace and normalises curly apostrophes before matching — without the apostrophe normalisation two quotes failed on a \u2019 versus \u0027 difference alone, which would have read as a bad quote.
Two quotes are located only in a second rendering of the PDF. The .cols column repair spliced two columns together on those pages, so the sentence does not exist in paper.cols.txt in readable order. bs_pypdf_render.py re-extracts the PDF with pypdf and the check falls back to it, reporting OK-pypdf rather than OK:
| Paper | Quote | What .cols produced instead |
|---|---|---|
| [5Ali, Mir Masood; Chitale, Binoy; Ghasemisharif, Mohammad; Kanich, Chris; Nikiforakis, Nick; Polakis, Jason (2023): "Navigating Murky Waters: Automated Browser Feature Testing for Uncovering Tracking Vectors", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] | “Safari and Brave use this approach for cookies and mechanisms under the Storage API, i.e., local storage, indexedDB, and cache storage” | …Safari and Brave use this was added by an iframe (iframe.com) while embedded in approach for cookies and mechanisms under the Storage API, another site (news.com). Starting from v87, Chrome keys i.e., local storage, indexedDB, and cache storage. Both paper.cols.txt and paper.norm.txt carry the same splice, so the column repair did not help here |
| [6Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)] | “all cookies, IndexedDB, LocalStorage, SessionStorage and WebSQL records are saved” | the same sentence interleaved with a neighbouring one about toplist choice |
A quote that was drafted and then rejected. An earlier draft attributed to [5Ali, Mir Masood; Chitale, Binoy; Ghasemisharif, Mohammad; Kanich, Chris; Nikiforakis, Nick; Polakis, Jason (2023): "Navigating Murky Waters: Automated Browser Feature Testing for Uncovering Tracking Vectors", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] the sentence “Starting from v87, Chrome keys i.e., local storage, indexedDB, and cache storage”, taken verbatim from paper.cols.txt. It is a splice of two different sentences and the paper does not say it. It was replaced with the two real sentences, and the pypdf fallback exists because of it.
And a bibliography entry that the same problem nearly broke. paper.cols.txt for [7Aggarwal, Gaurav; Bursztein, Elie; Jackson, Collin; Boneh, Dan (2010): "An Analysis of Private Browsing Modes in Modern Browsers", in: Proceedings of the USENIX Security Symposium. (Link)] shows only Gaurav Aggarwal Elie Bursztein / Stanford University on its title page; the pypdf rendering shows four authors (Aggarwal, Bursztein, Jackson, Boneh). The BibTeX entry uses all four. Do not take an author list from the .cols rendering.
- bs_quotecheck-output.txt
Got invalid hex string: Odd-length string (b'1F603') Exceeded 5000 form XObject invocations while extracting text; further form content is skipped. Ignoring wrong pointing object 154 0 (offset 0) OK IEEE-SP/2010/on-the-incoherencies-in-web-browser-access-control-policies "only 0.19% of the sites were using localStorage" OK USENIX/2016/internet-jones-and-the-raiders-of-the-lost-trackers-an-archaeological-study-of-w "the use of the localStorage API rises rapidly since its introduction in 2009, indicating t…" OK CCS/2014/the-web-never-forgets-persistent-tracking-mechanisms-in-the-wild "A very small number of sites, only 20 out of 100K, were found to use the IndexedDB storage…" OK WWW/2025/least-privilege-access-for-persistent-storage-mechanisms-in-web-browsers "find that 89.84% of all cookie accesses, 90.98% of all localstorage accesses, and 72.49% o…" OK WWW/2025/least-privilege-access-for-persistent-storage-mechanisms-in-web-browsers "in at least 16% of these third-party accesses, the third-party scripts read/modify cookies…" OK CCS/2023/cookiegraph-understanding-and-detecting-first-party-tracking-cookies "we found 217,444 unique first-party cookie names and 99,682 unique localStorage names" OK CCS/2023/cookiegraph-understanding-and-detecting-first-party-tracking-cookies "we found 13,571 instances where the same first-party cookie was also stored in local stora…" OK NDSS/2021/tales-of-favicons-and-caches-persistent-tracking-in-modern-browsers "this cache is not affected by user actions that clear other caches, local storages and bro…" OK NDSS/2021/tales-of-favicons-and-caches-persistent-tracking-in-modern-browsers "while browsers fully isolate other local storages and caches from the incognito mode that …" OK NDSS/2021/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage "the resource will be retrieved from the cache storage instead of being fetched over the ne…" OK NDSS/2021/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage "in the first visit to the website, where the resources are inserted into the cache storage…" OK NDSS/2019/dont-trust-the-locals-investigating-the-prevalence-of-persistent-client-side-cross-site-scripting-in-the-wild "virtually all flows that originate from a Local Storage source have no encoding applied to…" OK NDSS/2020/melting-pot-of-origins-compromising-the-intermediary-web-services-that-rehost-websites "around 40% of the top-10K websites including sensitive categories" OK PETS/2024/a-large-scale-study-of-cookie-banner-interaction-tools-and-their-impact-on-users "A site uses 12 (SD: 31; min: 1; max: 2,720) keys on average" OK PETS/2024/a-large-scale-study-of-cookie-banner-interaction-tools-and-their-impact-on-users "the data stored in local storage has a longer lifespan than cookies" OK PETS/2025/johnny-can-t-revoke-consent-either-measuring-compliance-of-consent-revocation-on "the TCString returned by __tcfapi showed negative consent, while the TCString stored in th…" OK USENIX/2025/big-help-or-big-brother-auditing-tracking-profiling-and-personalization-in-gener "Harpa and Copilot stored the complete chat history in the extension's background service w…" OK USENIX/2010/an-analysis-of-private-browsing-modes-in-modern-browsers "Of the top 100 extensions, we observed that 71 stored data to disk using the localStorage …" OK IMC/2020/when-push-comes-to-ads-measuring-the-rise-of-malicious-push-advertising "both ad blocking mechanisms failed to block the registration of Service Worker scripts" OK-pypdf NDSS/2023/navigating-murky-waters-automated-browser-feature-testing-for-uncovering-tracking-vectors (.cols spliced this sentence; located in the pypdf rendering) "Safari and Brave use this approach for cookies and mechanisms under the Storage API, i.e.,…" OK PETS/2023/your-drm-can-watch-you-too-exploring-the-privacy-implications-of-browsers-mis-im "Opera and Samsung do not treat the stored data like cookies or web storage" OK USENIX/2023/pool-party-exploiting-browser-resource-pools-for-web-tracking "WebKit partitions DOM storage and some kinds of network state, Gecko partitions DOM storag…" OK USENIX/2018/who-left-open-the-cookie-jar-a-comprehensive-evaluation-of-third-party-cookie-po "Service workers can be seen as a replacement for the deprecated AppCache API" OK IMC/2022/measuring-uid-smuggling-in-the-wild "Each of these redirectors has the ability to store the UID from the query parameter as a c…" OK USENIX/2025/web-execution-bundles-reproducible-accurate-and-archivable-web-measurements "service workers also live in their own context and are not recorded in .web behaviors" OK-pypdf PETS/2021/privacy-preference-signals-past-present-and-future (.cols spliced this sentence; located in the pypdf rendering) "all cookies, IndexedDB, LocalStorage, SessionStorage and WebSQL records are saved" OK PETS/2026/from-syntactic-matching-to-taint-tracking-and-back-a-comparative-study-of-web-tr "relies on the creation of unique identifiers that are first saved in the client-side stora…" OK PETS/2026/the-masks-we-think-we-wear-privacy-threats-of-browser-extension-wallets-in-the-w "localStorage are automatically cleared when users clear site data" OK WWW/2022/measuring-the-privacy-vs-compatibility-trade-off-in-preventing-third-party-state "local storage PITS are significantly less frequent than PICFs across our dataset globally,…" OK PETS/2021/defining-privacy-how-users-interpret-technical-terms-in-privacy-policies "we found that browser web storage is also not well understood; only 24% of respondents sel…" OK IMC/2020/when-push-comes-to-ads-measuring-the-rise-of-malicious-push-advertising "Easylist was able to filter a small number (less than 2%) of network requests subsequently…" OK IEEE-SP/2015/understanding-and-monitoring-embedded-web-scripts "Scripts from betrad.com also access localStorage APIs, presumably adding an extra tracking…" OK IEEE-SP/2010/on-the-incoherencies-in-web-browser-access-control-policies "no sites were using sessionStorage" OK CCS/2018/pride-and-prejudice-in-progressive-web-apps-abusing-native-app-like-features-in "we define a PWA as a website that registers a service worker at the browser of a page visi…" OK CCS/2024/blocking-tracking-javascript-at-the-function-granularity "The most important feature is the number of successor functions, a structural feature, fol…" 35 quotes: 33 exact in paper.cols.txt, 2 exact only in the pypdf rendering, 0 partial (8-word run located), 0 not found.
8. The three probes, and their unedited output
All three ran on Linux, Playwright 1.62.1 with its own Chromium build at PLAYWRIGHT_BROWSERS_PATH=/workspace/.playwright (the Debian /usr/bin/chromium wrapper cannot be driven by Playwright — see corpus and the gotcha list in contributing).
8.1 Storage readout
- readout-output.txt
Playwright 1.62.1, Chromium 151.0.7922.34 marker written to every store: ID-4b7f2a store page.evaluate() CDP storageState() storageState({indexedDB:true}) ---------------- ------------------ ---------------------------------- ---------------- ------------------------------ cookie ID-4b7f2a ID-4b7f2a ID-4b7f2a ID-4b7f2a localStorage ID-4b7f2a ID-4b7f2a ID-4b7f2a ID-4b7f2a sessionStorage ID-4b7f2a ID-4b7f2a MISSING MISSING indexedDB ID-4b7f2a ID-4b7f2a MISSING ID-4b7f2a cacheStorage ID-4b7f2a http://127.0.0.1:36849/cached.txt MISSING MISSING serviceWorkers 1 1 MISSING MISSING CDP IndexedDB databases seen: ["store"] CDP CacheStorage names seen: ["cachev1"] CDP IndexedDB.requestData with an empty indexName: cdpSession.send: Protocol error (IndexedDB.requestData): Could not get index
How the IndexedDB row was arrived at, because the first three attempts failed. IndexedDB.requestData returned Protocol error: Could not get index for every parameter combination tried with indexName: '': out-of-line and in-line key paths, with and without a well-formed keyRange, and with each of securityOrigin, storageKey and storageBucket as the selector. IndexedDB.requestDatabaseNames, IndexedDB.requestDatabase and IndexedDB.getMetadata all worked throughout, which is what made a mis-parameterisation more likely than a broken domain. Omitting the indexName field works. The current protocol definition marks the parameter optional — “Index name. If not specified, it performs an object store data request.” — so the empty string is not a documented form; it is, however, what a lot of example code passes. The failing call is kept in the published script as an assertion so that a future Chromium change surfaces as a changed line of output.
bs_probe/_idbtest.mjs and bs_probe/_idbtest2.mjs are the throwaway scripts that established this; they are kept in the workdir, unpublished.
8.2 Third-party storage partitioning
- partition-output.txt
Chromium 151.0.7922.34 Playwright's default: --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,BlockOriginHeaderModificationOnRedirect,Translate,AutoDeElevate,OptimizationHints,msForceBrowserSignIn,msEdgeUpdateLaunchServicesPreferredVersion Playwright default site A wrote TP-VALUE, site B read TP-VALUE -> NOT partitioned partitioning re-enabled site A wrote TP-VALUE, site B read null -> PARTITIONED Puppeteer 25.9.0 default site A wrote TP-VALUE, site B read null -> PARTITIONED
Three arms, one browser binary. Puppeteer is pointed at Playwright's Chromium via executablePath, so the engine build is byte-identical across all three rows and the only difference is the automation library's default flags.
The control arm needed two attempts. Passing –enable-features=ThirdPartyStoragePartitioning alone changes nothing, because Playwright also passes ThirdPartyStoragePartitioning inside its single –disable-features= argument and disable beats enable. The published script reads the live command line via Browser.getBrowserCommandLine (which itself requires –enable-automation, or Chromium refuses with “Command line not returned because –enable-automation not set”), drops the whole default argument with ignoreDefaultArgs, and passes it back minus the one feature. Reading the list from the running browser rather than hard-coding it means the probe keeps working when Playwright changes its defaults.
What this probe does not show. It tests localStorage only, on plain-HTTP loopback origins, in one Chromium version, headless. It does not test IndexedDB or Cache Storage (which Chrome partitions under the same flag), does not test Firefox (Playwright's Firefox cannot start in this container — headless dies with RenderCompositorSWGL failed mapping default framebuffer), and says nothing about cookies. The Puppeteer row confirms what Since 2022 the engine decides, not you reports for cookies, on the storage axis, but is not a re-measurement of that page's cookie result.
8.3 Clear-Site-Data
- csd-output.txt
Chromium 151.0.7922.34, origin http://127.0.0.1:42197 (plain HTTP, treated as a secure context because it is 127.0.0.1) Clear-Site-Data: cookie localStorage sessionStorag indexedDB cacheStorage serviceWorker httpCache ---------------------------------------------- -------------- -------------- -------------- -------------- -------------- -------------- "cookies" cleared SURVIVED SURVIVED SURVIVED SURVIVED SURVIVED SURVIVED "storage" SURVIVED cleared cleared cleared cleared cleared SURVIVED "cache" SURVIVED SURVIVED SURVIVED SURVIVED SURVIVED SURVIVED cleared "cookies", "storage", "cache" cleared cleared cleared cleared cleared cleared cleared "*" cleared cleared cleared cleared cleared cleared cleared "cleared" means the value was absent on the next load; "SURVIVED" means it was still there. httpCache is observed indirectly: an `immutable` subresource that is re-requested from the origin after the header means the cache entry was dropped.
Its source, in full, because the content page carries only the table:
- clear_site_data_probe.mjs
// `Clear-Site-Data` as a measurement instrument: a server-side reset of one // origin's client-side state, which is what you want for a paired-visit design // (visit, reset one origin only, revisit) rather than throwing the whole // browser context away. // // Measured here: which of cookie / localStorage / sessionStorage / IndexedDB / // Cache Storage / service-worker registration each directive actually removes. // // Run: PLAYWRIGHT_BROWSERS_PATH=/workspace/.playwright node clear_site_data_probe.mjs import http from 'node:http'; import { chromium } from 'playwright'; const MARK = 'ID-4b7f2a'; const SET = `<!doctype html><meta charset=utf-8><script> window.__ready = (async () => { document.cookie = 'ck=${MARK}; SameSite=Lax; max-age=3600'; localStorage.setItem('ls', '${MARK}'); sessionStorage.setItem('ss', '${MARK}'); await new Promise((res, rej) => { const r = indexedDB.open('store', 1); r.onupgradeneeded = () => r.result.createObjectStore('kv'); r.onsuccess = () => { const tx = r.result.transaction('kv', 'readwrite'); tx.objectStore('kv').put('${MARK}', 'idb'); tx.oncomplete = () => { r.result.close(); res(); }; tx.onerror = () => rej(tx.error); }; r.onerror = () => rej(r.error); }); await (await caches.open('cachev1')).put('/c.txt', new Response('${MARK}')); await navigator.serviceWorker.register('/sw.js'); return 1; })(); </script>`; const READ = `<!doctype html><meta charset=utf-8><script> window.__read = (async () => { const idb = await new Promise((res) => { const r = indexedDB.open('store', 1); r.onupgradeneeded = () => r.result.createObjectStore('kv'); // absent => fresh db r.onsuccess = () => { const g = r.result.transaction('kv', 'readonly').objectStore('kv').get('idb'); g.onsuccess = () => { const v = g.result ?? null; r.result.close(); res(v); }; g.onerror = () => { r.result.close(); res(null); }; }; r.onerror = () => res(null); }); const names = await caches.keys(); const hit = names.includes('cachev1') ? await (await caches.open('cachev1')).match('/c.txt') : null; return { cookie: /ck=([\\w-]+)/.exec(document.cookie)?.[1] ?? null, localStorage: localStorage.getItem('ls'), sessionStorage: sessionStorage.getItem('ss'), indexedDB: idb, cacheStorage: hit ? await hit.text() : null, serviceWorker: (await navigator.serviceWorker.getRegistrations()).length || null, }; })(); </script>`; let directive = null; let subresourceHits = 0; // the HTTP-cache observable: a miss re-hits the origin const server = http.createServer((req, res) => { if (req.url === '/immutable.js') { subresourceHits++; res.writeHead(200, { 'content-type': 'application/javascript', 'cache-control': 'public, max-age=31536000, immutable' }); return res.end('window.__sub = 1;'); } if (req.url === '/sw.js') { res.writeHead(200, { 'content-type': 'application/javascript', 'cache-control': 'no-store' }); return res.end('self.addEventListener("install", () => self.skipWaiting());'); } const headers = { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' }; if (req.url.startsWith('/clear') && directive) headers['Clear-Site-Data'] = directive; res.writeHead(200, headers); res.end((req.url === '/set' ? SET : READ) + '<script src="/immutable.js"></script>'); }); await new Promise((r) => server.listen(0, '127.0.0.1', r)); const ORIGIN = `http://127.0.0.1:${server.address().port}`; const STORES = ['cookie', 'localStorage', 'sessionStorage', 'indexedDB', 'cacheStorage', 'serviceWorker', 'httpCache']; const browser = await chromium.launch(); console.log(`Chromium ${browser.version()}, origin ${ORIGIN} (plain HTTP, treated as a secure context because it is 127.0.0.1)\n`); const results = []; for (const d of ['"cookies"', '"storage"', '"cache"', '"cookies", "storage", "cache"', '"*"']) { directive = d; const context = await browser.newContext(); const page = await context.newPage(); await page.goto(ORIGIN + '/set'); await page.evaluate(() => window.__ready); await page.evaluate(() => navigator.serviceWorker.ready); // `controller` is null, not undefined, before control await page.goto(ORIGIN + '/read'); // warm the HTTP cache for the subresource await page.goto(ORIGIN + '/clear'); // response carries the header const after = await page.evaluate(() => window.__read); // Two loads have happened since /set; if the subresource was re-fetched after // the header, the HTTP cache entry was dropped. // The HTTP-cache read has to happen in a FRESH page: Chromium's per-renderer // in-memory resource cache would otherwise serve the subresource without ever // consulting the disk cache, making the observable insensitive. const hitsBefore = subresourceHits; await page.close(); const page2 = await context.newPage(); await page2.goto(ORIGIN + '/read'); after.httpCache = subresourceHits > hitsBefore ? null : 'still cached'; results.push([d, after]); await context.close(); } console.log('Clear-Site-Data:'.padEnd(32) + STORES.map((s) => s.slice(0, 13).padEnd(15)).join('')); console.log('-'.repeat(32) + STORES.map(() => '-'.repeat(14) + ' ').join('')); for (const [d, after] of results) { console.log(d.padEnd(32) + STORES.map((s) => (after[s] === null ? 'cleared' : 'SURVIVED').padEnd(15)).join('')); } console.log('\n"cleared" means the value was absent on the next load; "SURVIVED" means it was still there.'); console.log('httpCache is observed indirectly: an `immutable` subresource that is re-requested from the origin'); console.log('after the header means the cache entry was dropped.'); await browser.close(); server.close();
The HTTP-cache column was wrong twice before it was right. First attempt: no HTTP-cache observable at all, so the "cache" row showed every store surviving and looked like evidence that the directive does nothing. Second attempt: an immutable subresource added as an observable, read from the same page — still all-survived, because Chromium's per-renderer in-memory resource cache serves the subresource without consulting the disk cache. Third attempt, the published one: the read happens in a fresh context.newPage(), and the "cache" and "*" rows come out cleared. The intermediate result would have been publishable-looking and false, which is why the sequence is recorded here.
The origin is 127.0.0.1, which browsers treat as a secure context, so Clear-Site-Data is honoured over plain HTTP. On a non-loopback HTTP origin it would be ignored.
9. Judgement calls
- New page, not a section of cookies.
privacy:cookiesis titled “Classifying Cookies” and is about assigning a purpose to a cookie: categories, label databases, CookieBlock and CookieGraph. The material here is about a different question (which stores exist, can your instrument see them, what removes them) with a different literature and different failure modes, and it needs three tested tables that would swamp a cookie-classification page. The privacy namespace page's own framing — one page per classification target — also argues for a sibling. A reasonable person could have made it a long section ofprivacy:cookiesinstead; if that is the call, the merge point is afterprivacy:cookies's “Categories” section. - Not folded into stateful_stateless either. That page owns “what does a reset reset” and already measures it well. The overlap is one section here, which points at it rather than restating its table, and adds only the two things it does not cover: the per-origin
Clear-Site-Datareset, and the browser deleting state on its own timers. The partitioning section deliberately measures the storage axis where that page measured the cookie axis. - Tier B is published rather than discarded. 49 papers instrument or model a store without measuring it. They are the right citations for a methods section and the wrong ones for a results claim, and separating them is most of the value of the audit. A run that reported only “43 papers” would have hidden the distinction.
- The compliance-gap figures are mention tests and are labelled as such three times. “35 of 402 papers name a non-cookie store” is not “367 papers checked only cookies”. The Tier A count (4) is the hand-audited claim; the mention count is the upper bound on how many could have.
- “Fewer than three a year” is arithmetic on a hand-audited set of 43 over 17 venue-years, and it is a claim about seven venues. WPES, where a good deal of storage work has appeared, is not in the corpus. That caveat is on the content page.
- No LLM-based storage classification is claimed either way. Unlike requests, this page does not assert that the method is absent from the literature, because no targeted outside-corpus search for it was run. §10 lists that as a gap rather than as a finding.
- Three Tier A assignments are borderline, and a reasonable person could put them in B.
NDSS/2026/are-your-sites-truly-isolated…measures whether browsers isolatelocalStorageand IndexedDB correctly — the store is the object of measurement, but the population measured is browsers, not sites.IEEE-SP/2018/surveylance…monitors survey-scam sites' use of the Web Storage APIs and searches HTTP traffic for the stored values, which is a property of the measured sites but is not reported as a prevalence figure.CCS/2024/peeking-through-the-window…was checked specifically because most of its storage text is background exposition; it stays in A because Tables 4 and 5 carry aStoragerow with per-extension counts (634 / 623 / 391 / 266), so extensions' storage traces are measured. Moving all three to B would change the Tier A count from 43 to 40 and the precision from 35.8% to 33.3%. - The favicon cache and the HTTP cache are in scope; CPU and CDN caches are not. The boundary is “a store the browser keeps per site, that a page can cause to be written”. That excludes microarchitectural caches (three candidate papers), CI build caches (one), and proxy cache sizing (one), all named in the audit table with that reason.
10. What could not be established
- Whether the 90.98% / 72.49% third-party access shares replicate. One paper, one crawl, Tranco top 10,000, 2025. Read directly from the paper: the instrument is “the Nightly Firefox version 98.0a1 (64-bit) browser”, modified to log accesses, and the list is
tranco-list.eu/list/LYLP4/. Firefox 98 predates the Firefox 103 cookie-partitioning default, and the measure is who performs the access in the first-party context rather than whether a value is shared across sites — so the figure is not directly comparable to a partitioning result, and the content page states it as an access share for that reason. - Whether the field's storage coverage is actually flat or merely looks flat. The Tier A share per bucket (0.8%, 0.4%, 0.8%, 0.9%, 0.7%) is computed on a hand-audited set of 43, so the bucket counts are 4, 3, 11, 17 and 8 — too small to distinguish “no trend” from noise, and the buckets are not equal widths (four, four, four, three and two years). The page now says “no detectable trend”, carries the sample-size caveat and names the bucket widths; the series is shown rather than suppressed because a reader who wants to argue with it can see everything it is made of.
- A per-store count for Cookiedatabase.org. Its front page states it covers Local Storage; its public WordPress REST namespaces expose no cookie or storage collection, and no export endpoint was found. The page therefore cites it as a lead, explicitly not as a resource with known coverage.
- Whether the CookieBlock feature set transfers to
localStorage. Raised as an open question on the page. Not testable from the corpus: nobody has published storage-key labels to train or evaluate against. - Firefox behaviour, measured. Every measurement in §8 is Chromium. The Firefox claims on the page rest on Mozilla's and MDN's documentation, and are attributed to it.
- Whether any of the 174 residue papers is Tier A. They were not audited. Two were spot-checked (§5) and both were correctly excluded, which is not evidence about the other 172.
11. External sources, and how each was verified
All checked 2026-08-31. Each row names the primary source actually fetched, not a summary of it.
| Claim on the page | Primary source fetched | What it says |
|---|---|---|
| Chrome partitions third-party storage for all users since 115; cookies are not part of it | privacysandbox.google.com/cookies/storage-partitioning | “The feature has been enabled for all users on Chrome 115 and later.” Partitioned: quota system (IndexedDB, Cache storage), Web Storage API, Origin Private File System, Storage Bucket API, Clear-Site-Data, Blob URL store. Cookies are handled separately (CHIPS, Storage Access API) |
| Firefox partitions those APIs statically, cookies dynamically since 103 | MDN Web/Privacy/Guides/State_Partitioning | Dynamic partitioning (cookies) default for all users since Firefox 103; localStorage, sessionStorage, DOM Cache, IndexedDB, BroadcastChannel, SharedWorker and ServiceWorker are statically partitioned, i.e. always |
| WebKit's seven-day cap, and which stores it covers | webkit.org/tracking-prevention plus webkit.org/blog/10218 (24 March 2020) | “ITP deletes all cookies created in JavaScript and all other script-writeable storage after 7 days of no user interaction with the website”; storage named: IndexedDB, LocalStorage, media keys, SessionStorage, Service Worker registrations and cache. The tracking-prevention page is undated, so the page presents this as WebKit's current documented behaviour and not as version-pinned |
| WebSQL removed in Chromium 119 | developer.chrome.com/blog/deprecating-web-sql | Insecure contexts from Chromium 110; “Web SQL access in all contexts is no longer available from Chromium 119”; enterprise policy and deprecation trial ended at 123 |
| Chrome bounce-tracking mitigations delete site storage after 45 days without interaction | privacysandbox.google.com/protections/bounce-tracking-mitigations | “If the site does not have any user interaction recorded within the last 45 days and third-party cookies are blocked, then the site storage will be deleted shortly after the next redirection flow is triggered through this site.” “launched by default in Chrome in October 2023 for users who have opted-in to blocking third-party cookies” |
Playwright's storageState() contents and the indexedDB option | playwright.dev/docs/api/class-browsercontext | Returns “cookies, local storage snapshot, IndexedDB snapshot and virtual WebAuthn credentials”; indexedDB: “Set to true to include IndexedDB in the storage state snapshot”, off by default. sessionStorage is not mentioned anywhere in the method's documentation — consistent with the measured MISSING |
CDP IndexedDB.requestData parameter semantics | chromedevtools.github.io/devtools-protocol/tot/IndexedDB and ChromeDevTools/devtools-protocol json/browser_protocol.json | indexName is optional: “Index name. If not specified, it performs an object store data request.” Required: databaseName, objectStoreName, skipCount, pageSize; exactly one of securityOrigin / storageKey / storageBucket |
Playwright 1.48.0 (8 October 2024) is the first release that disables ThirdPartyStoragePartitioning | registry.npmjs.org tarballs for playwright-core 1.47.0 and 1.48.0, unpacked and grepped | the string is absent from 1.47.0 and present in 1.48.0. The commit is 5089d9f, “fix(chromium): disable ThirdPartyStoragePartitioning” (PR 32701), dated 2024-09-19 in the microsoft/playwright history. This bounds the window in which a default Playwright crawl differed from real Chrome: Chrome partitioned in July 2023, Playwright opted out in October 2024 |
Playwright disables ThirdPartyStoragePartitioning; Puppeteer does not | the repository source and the running browser | node_modules/playwright-core/lib/coreBundle.js, the bundled chromiumSwitches.ts disabledFeatures list, with the comment “See github.com/microsoft/playwright/issues/32230”; and Browser.getBrowserCommandLine on the launched process, whose –disable-features= argument is quoted in full in §8.2. Puppeteer's absence of the flag is inferred from the measured PARTITIONED result, not from reading its source |
| OpenWPM's instrumentation coverage | shallow clone of github.com/openwpm/OpenWPM at tag v0.36.0 (commit 61d285fc, released 2026-08-24, Firefox 154) | cookie_instrument: bool = True; js_instrument: bool = False; collection_fingerprinting includes Storage, window.localStorage, window.sessionStorage; grep -rni indexeddb over the whole tree returns 0 matches; profile_commands.py required_items is cookies.sqlite, places.sqlite, storage.sqlite; CHANGELOG.md records the Firefox 137 webappsstore.sqlite → storage.sqlite migration |
| ePrivacy Art 5(3) scope | EDPB Guidelines 2/2023, PDF fetched from edpb.europa.eu and re-extracted locally with pypdf | Cover page: “Version 2.0, Adopted on 7 October 2024”; version history gives 1.0 as 14 November 2023 for public consultation. §3 use cases: URL and pixel tracking, local processing, tracking based on IP only, intermittent and mediated IoT reporting, unique identifier. ¶43 names caching mechanisms “such as ETag”; ¶44 names “cookies, local storage, WebSQL”. Quoted sentence on the page is from ¶50 |
| Open Cookie Database has no store-type field | raw.githubusercontent.com/jkwakman/Open-Cookie-Database/master/open-cookie-database.csv | 2,266 data rows. Header: ID,Platform,Category,Cookie / Data Key name,Domain,Description,Retention period,Data Controller,User Privacy & GDPR Rights Portals,Wildcard match. Last commit 2026-08-21 |
| Chrome stable version on the day of the run | versionhistory.googleapis.com/v1/chrome/platforms/linux/channels/stable/versions | 152.0.7977.64 |
| Quota, LRU eviction, and the ~5 MiB Web Storage cap | MDN Web/API/Storage_API/Storage_quotas_and_eviction_criteria | Web Storage capped at 10 MiB total (5 MiB localStorage + 5 MiB sessionStorage) per origin in all browsers; quota-managed storage up to 60% of disk in Chrome; “The data from the least recently used origin is deleted”; “When an origin's data is evicted by the browser, all of its data, not parts of it, is deleted at the same time”; eviction skips origins granted persistence via navigator.storage.persist() |
11.1 Deferred rather than verified
| Claim | Status |
|---|---|
| Digital Omnibus (COM(2025) 837 final, 19 November 2025) | The page's one-sentence pointer defers to legal_enforcement, which already carries the verified quotes from the explanatory memorandum and the enacting text, the procedure number 2025/0360(COD) and its status as read from the Legislative Observatory on 2026-08-18. Deliberately not duplicated and not independently re-verified in this run; if that page's status line has gone stale, this page's sentence goes stale with it |
11.2 Sources rejected, and why
| Source | Why it is not on the page |
|---|---|
developer.chrome.com/docs/privacy-security/storage-partitioning | HTTP 404. The live document is under privacysandbox.google.com; the developer.chrome.com path is stale and would have been a dead link |
developer.chrome.com/blog/bounce-tracking-mitigations | HTTP 404. Replaced with the Privacy Sandbox page, which is the primary one |
support.mozilla.org/en-US/kb/total-cookie-protection | Fetched a JavaScript shell with no content. MDN's State Partitioning page was used instead, and is the more precise source anyway because it distinguishes static from dynamic partitioning |
chromestatus.com/feature/5705149616488448 (Bounce Tracking Mitigations) | Client-rendered; the fetch returned only the page title. Not used |
A web search result set on the CDP Could not get index error | Returned only loosely related Chromium IndexedDB corruption bugs, none about the CDP command. The page's claim rests on the local measurement plus the protocol definition, not on that search |
cookiedatabase.org REST API | No cookie or storage collection in the exposed namespaces; wp-json/cookiedatabase/v1/cookies returns rest_no_route. The page cites the site's own coverage statement and says the count could not be established |
developer.chrome.com/docs/apps/offline_storage | Describes quota and LRU eviction, but for Chrome Apps, which the page itself says were deprecated in 2020. Its “20% of the shared pool” and “1/3 of available disk” figures do not describe modern web storage. MDN's Storage API page was used instead |
usenix.org via WebFetch | HTTP 403 on the PDF path, as the site brief warns. Author lists were taken from the HTML landing pages with curl and a browser User-Agent, and from the paper PDF via pypdf for the 2010 paper whose landing page is a session index |
12. Bibliography
15 entries added to bibliography, appended before the closing </bibtex>. Every key was checked against the live export for collisions (none), every DOI and URL was checked against the live bibliography for the same paper under a different key (none), and a title-similarity scan against all 703 existing entries found no near-duplicate above 0.72.
| Key | Paper | Identifier, and how it was verified |
|---|---|---|
kancherla2025_least | Least Privilege Access for Persistent Storage Mechanisms in Web Browsers, WWW 2025 | 10.1145/3696410.3714887 — Crossref title match |
karami2021_awakening | Awakening the Web's Sleeper Agents, NDSS 2021 | no DOI; NDSS landing URL, HTTP 200 |
lee2018_pride | Pride and Prejudice in Progressive Web Apps, CCS 2018 | 10.1145/3243734.3243867 — Crossref title match |
watanabe2020_melting | Melting Pot of Origins, NDSS 2020 | no DOI; NDSS landing URL, HTTP 200 |
mishra2021_dejavu | Déjà vu: Abusing Browser Cache Headers, PETS 2021 | 10.2478/popets-2021-0033, resolves 200. Authors fetched from the PoPETs landing page; the index record has none |
ali2023_navigating | Navigating Murky Waters, NDSS 2023 | no DOI; NDSS landing URL, HTTP 200 |
snyder2023_poolparty | Pool-Party, USENIX Security 2023 | no DOI; USENIX landing URL, HTTP 200. Authors from the landing page |
aggarwal2010_analysis | An Analysis of Private Browsing Modes in Modern Browsers, USENIX Security 2010 | no DOI; PDF URL, HTTP 200. Authors from the PDF title page via pypdf — see §7 |
franken2018_cookiejar | Who Left Open the Cookie Jar?, USENIX Security 2018 | no DOI; USENIX landing URL, HTTP 200. Authors from the landing page |
singh2010_incoherencies | On the Incoherencies in Web Browser Access Control Policies, IEEE S&P 2010 | 10.1109/sp.2010.35, resolves |
patat2023_drm | Your DRM Can Watch You Too, PETS 2023 | 10.56553/popets-2023-0112, resolves 200. Authors from the landing page |
liu2024_promises | From Promises to Practice, WWW 2024 | 10.1145/3589334.3645320 — Crossref title match |
vekaria2025_bighelp | Big Help or Big Brother?, USENIX Security 2025 | no DOI; USENIX landing URL, HTTP 200. Authors from the landing page |
wang2026_masks | The Masks We (Think We) Wear, PETS 2026 | 10.56553/popets-2026-0094, resolves 200. Authors from the landing page |
zhou2015_monitoring | Understanding and Monitoring Embedded Web Scripts, IEEE S&P 2015 | 10.1109/sp.2015.57, resolves |
The PoPETs DOI prefix is version-dependent (10.1515 to 2018, 10.2478 to 2022-0058, 10.56553 from 2022-0059); bibgen.mjs derives it and all three new PoPETs DOIs were resolved directly rather than trusted.
Keys reused from the existing bibliography, not re-verified here: acar2014_never, solomos2021_tales, fouad2022my, shaoor2023cookiegraph, bollinger2022automating, englehardt2016online, lerner2016internet, steffens2019_dont, subramani2020_push, jueckstock2022_privacy, demir2024_bannertools, kancherla2025_johnny, hils2021_privacy, hantke2025web.
13. The run itself
| Item | Value |
|---|---|
| Date | 2026-08-31 |
| Corpus at the time | 5,859 extracted papers, 7 venues (CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf, IEEE S&P), 2010–2026; data/extract/run1, corpus as extended 2026-08-11 (commit 8a6b843) |
| Page before | privacy:browser_storage did not exist. The reported “before” size on save is the i_template pre-fill, not zero |
| Scripts written | bs_fold.mjs (population + hand audit), report_browser_storage.mjs, bs_quotecheck.mjs, bs_pypdf_render.py, bs_probe/storage_readout.mjs, bs_probe/partition_probe.mjs, bs_probe/clear_site_data_probe.mjs |
| Throwaway probes kept in the workdir | scripts/_bs_probe1..7.mjs (term sweeps, threshold distribution, triage snippets, audit sentences), bs_probe/_idbtest.mjs, bs_probe/_idbtest2.mjs, bs_probe/_partition_probe.mjs |
| Bibliography entries added | 15 |
| Environment change | puppeteer 25.9.0 was installed into the workdir for the three-arm partitioning probe. A package.json was added at the workdir root because npm install –no-save had silently removed playwright from node_modules — the workdir had no manifest, so npm pruned everything it did not know about. Anyone reusing this workdir should keep that manifest |
| Models | Opus 5 wrote the page, the fold, the report script and the probes. Review layer: three Sonnet passes (figures versus script; citations and quotes; external currency) and one Fable generic pass, recorded in §14 |
| Accidental exposure | None. Credentials stayed in .env; no authenticated request was made to any third party. GitHub, Crossref, doi.org, the EDPB, USENIX, PoPETs and NDSS were all fetched unauthenticated |
| Mistakes caught in review, by me, before any reviewer saw the page | Three, all in §7 and §8: a spliced quote presented as a paper's own sentence; a Flash-LSO regex that matched the word “also” and fired on 5,819 of 5,859 papers; and an HTTP-cache column that read “survived” for two iterations because the observable was insensitive |
14. Review passes
Four reviewers, run against a copy of the page in review_bs/.
A process fault, recorded because the privacy:requests provenance page warns about exactly this one and it happened anyway. review_bs/ was refreshed while the generic pass and the re-verification pass were still running, so those two reviewers read a moving target: some of what they saw had already been fixed, and some had been changed after they started. The three findings that arrived from the first round were applied correctly, but “freeze, review, then apply” was again not followed, and the disposition table below has to be read with that in mind. Each was told explicitly that the author's context may not be exhaustive and that nothing should be assumed verified. Every finding is listed, accepted or rejected, because a rejection is the only record of whether a reviewer earns its slot.
14.1 Figures versus the script (Sonnet)
Re-ran report_browser_storage.mjs and diffed: zero difference from the committed output. Checked ~15 script-derived figures, 6 literature figures against source PDFs, and both published code blocks.
| # | Finding | Disposition |
|---|---|---|
| 1 | The published storage_readout.mjs block had drifted from bs_probe/storage_readout.mjs: the comment and the log label described indexName differently in the two copies | Accepted, already fixed at the time the report arrived. The two files had been resynced by extracting the page's blocks back into bs_probe/ and re-running them; difflib now reports 0 diff lines each. The reviewer read the frozen copy and was right about the freeze. One correction to its account: the page's “optional” wording is the accurate one — the current browser_protocol.json marks indexName optional — and the script's older “documented as required” comment was the stale side |
| 2 | consentAction !== “not-stated” counts not-applicable as a stated value: 236 of 1,120 crawled papers carry it, so the population was 585 where OVERVIEW.md publishes 349 | Accepted and fixed. Filter now uses isSentinel(); the row is 349 / 66 / 18.9%. Recorded in §2.3. This is the most valuable finding of the review layer and it was a rule this run had written down and then broken anyway |
| 3 | “sixteen years” should be seventeen for 2010–2026 inclusive | Accepted, already changed to “seventeen years” before the report arrived |
| 4 | Four literature-table citekeys were outside the script's FIGURES self-check | Accepted. Three now have a detection tuple in FIGURES; the two that have no matching tuple are named in a comment in the script so they do not look self-checked when they are only quote-checked |
14.2 Citations and quotes (Sonnet)
Checked all 29 citekeys, all 15 new BibTeX entries (8 against Crossref, 7 against venue landing pages or the PDF title page), 17 of the 36 quotes re-verified independently against source text, ~20 further numeric claims read out of the source papers, and all 9 non-academic primary sources. It also independently cloned OpenWPM at v0.36.0 and reproduced every grep result quoted in §11, including grep -rni indexeddb returning 0.
No findings. Nothing accepted or rejected because nothing was reported. Note that this pass confirmed the aggarwal2010_analysis author-list problem independently, arriving at the same four authors from the PDF.
14.3 External currency (Sonnet)
| # | Finding | Disposition |
|---|---|---|
| 1 | The storage-partitioning footnote implied one Chrome 115 rollout for a list that includes the Blob URL store, which the same source dates to Chrome 137 (27 May 2025); and the source groups the affected APIs more broadly than the footnote's storage-only list | Accepted and fixed. The footnote now separates the Chrome 115 storage-API rollout from the Blob URL store's Chrome 137 date and names the four API groups |
| 2 | OpenWPM v0.36.0 was released 2026-08-24, not 2026-08-23 (tag object 2026-08-24T22:59:17Z, release published_at 2026-08-24T23:15:21Z) | Accepted and fixed on both pages |
| 3 | The legal section gives no signal that the frame is a live legislative target: the Commission's Digital Omnibus proposal of 19 November 2025 would move terminal-equipment consent for natural persons' personal data into the GDPR | Accepted, with a deliberate limit. A one-sentence pointer was added to the page. It defers to legal_enforcement, which already carries the verified quotes, the procedure number and the status, rather than restating them — and §11.1 records that this run did not independently re-verify that status |
It also confirmed, by fetch, every other external claim on both pages, and that Playwright 1.62.1 is the current release bundling Chromium 151.0.7922.34 while Chrome stable is 152.0.7977.64. Its one self-reported wobble is worth repeating: an initial summarised fetch of the Open Cookie Database reported “516 rows”, which a direct curl | wc -l corrected to 2,266 — the same failure mode this page's own footnotes exist to prevent.
14.4 Generic pass (Fable)
The most productive of the four. Fourteen findings, of which twelve were accepted.
| # | Finding | Disposition |
|---|---|---|
| 1 | The Playwright warning was mis-dated. Playwright only started disabling ThirdPartyStoragePartitioning in 1.48.0 (PR 32701, merged 2024-09-19), so a default Playwright crawl between Chrome 115 (July 2023) and October 2024 did partition and was wrongly indicted | Accepted and fixed, with the version boundary verified independently by unpacking the playwright-core 1.47.0 and 1.48.0 npm tarballs (§11). The page now names both dates |
| 2 | Direct contradiction with stateful_stateless, which says storageState() “serialises cookies, localStorage and IndexedDB” — measured here as IndexedDB MISSING unless { indexedDB: true } is passed | Accepted. The sibling page's sentence was corrected in the same sitting, and the correction is noted in the edit summary. This is the single most useful finding for a reader, because the sibling's advice silently ships a seed profile with no IndexedDB |
| 3 | The lead box said “Nobody is counting it” one sentence after naming the paper that counts it; claimed “the same size” for what is a share of accesses; and shifted denominators between 1,120 and 5,859 without saying so | Accepted and fixed, all three |
| 4 | “none of them say so as a limitation” is an unaudited absence claim that a mention probe cannot support | Accepted and fixed. The page now says explicitly that the probe cannot answer it |
| 5 | Publishing breaks the privacy namespace page's “All 9 children below are written” | Accepted. The namespace edit ships in the same sitting: count to 10, a table row, and “four views” to “five views” |
| 6 | The 89.86% CookieGraph figure has one denominator on cookies (“top-million”) and another in this run's tables (“top 20K”) | Accepted, and the reviewer's steer was half right. Reading the paper: the 20K crawl is a stratified sample of the top million, not the top 20,000, and the 89.86% comes from a separate 20%-of-top-million deployment. So privacy:cookies is right and this page's draft was wrong; the row now describes the stratification. §6.2 records it |
| 7 | “per four-year bucket” mislabels buckets that are four, four, four, three and two years | Accepted and fixed |
| 8 | The WebSQL row's jab at an unnamed 2023 paper was unfair — WebSQL was supported when that paper was written | Accepted and fixed. The row now names [5Ali, Mir Masood; Chitale, Binoy; Ghasemisharif, Mohammad; Kanich, Chris; Nikiforakis, Nick; Polakis, Jason (2023): "Navigating Murky Waters: Automated Browser Feature Testing for Uncovering Tracking Vectors", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] and says it was right at the time |
| 9 | §10 of this page criticised page wording that the page no longer had — the fix-survives-in-the-provenance-log pattern in reverse | Accepted and fixed |
| 10 | House style puts the todo box around Open Questions and leaves What to Report a plain ordered list; this page had it the other way round, which tells the reader the reporting checklist is the unfinished part | Accepted and fixed, after checking requests and stateful_stateless |
| 11 | “Nobody has repeated…” and “nobody has looked” are unbounded where the neighbouring bullet correctly says “no corpus paper” | Accepted and fixed; both bounded to the corpus, with a note that no outside search was run |
| 12 | waitForFunction(() ⇒ navigator.serviceWorker.controller !== undefined) waits for nothing: controller is null, not undefined, before a page is controlled, and the test worker never calls clients.claim() | Accepted and fixed in both probes (now navigator.serviceWorker.ready), and both re-run. Results unchanged, because what the readout reads is registration and not control. This is the finding that stings: the page's own thesis is that a check can pass while asserting nothing, and it was publishing one |
| 13 | The “36 quotes” list contained the same [2Lee, Jiyeon; Kim, Hayeon; Park, Junghwan; Shin, Insik; Son, Sooel (2018): "Pride and Prejudice in Progressive Web Apps: Abusing Native App-like Features in Web Applications", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] quote twice | Accepted and fixed: de-duplicated to 35, and the page's count updated |
| 14a–c | “write the word localStorage” understates the probe (it also matches “Web Storage”/“DOM storage”); “the practical effect is measured” introduced an explanation rather than a measurement; “every crawler records these” is an absolute | Accepted and fixed, all three |
| 14d | The OpenWPM section implied writing a profile reader is the only route to IndexedDB, omitting that js_instrument_settings takes arbitrary objects | Accepted and fixed, marked untested because we read the schema rather than running a crawl with it |
| 14e | The Digital Omnibus row rendered as a detached headerless one-row table | Accepted and fixed; it is now its own §11.1 with a header |
Nothing was rejected outright. Finding 6 was accepted with a correction to its own reasoning, which is recorded above rather than quietly absorbed.
14.5 Re-verification after the round-one fixes (Sonnet)
Run against the corrected artefacts, with an explicit instruction to mutate the published scripts rather than read them.
- Items 1–7 (sentinel fix, published-code identity, OpenWPM date, partitioning footnote, script re-run diff, every page figure, structural audit): all PASS. ~25 figures and 60+ numeric cells re-checked, 0 wrong. No other sentinel comparison, tuple-counted-as-paper, or mismatched numerator/denominator was found.
- Item 8, mutation testing: removing
{ indexedDB: true }flipped the IndexedDB cell to MISSING; corrupting the"storage"directive flipped that whole row to SURVIVED. Both assertions are real. But removing theignoreDefaultArgsline alone did not change the partitioning result — Chromium takes the last–disable-featuresit is given, so the replacement argument is doing the work on its own. Accepted: the page no longer impliesignoreDefaultArgsis load-bearing. The naive one-line fix (–enable-featuresalone) does still fail, which is the claim the section rests on. - It also noted that the script's line “4 of 5859 papers … are excluded from every full-text figure below” is imprecise — those four stay inside every denominator and simply score zero. Accepted as a wording defect; no published number is affected.
- And that §14.4 was still a placeholder when it ran. Correct: it was, and it is not now.
References
- [1]
- Munir, Shaoor; Siby, Sandra; Iqbal, Umar; Englehardt, Steven; Shafiq, Zubair; Troncoso, Carmela (2023): "CookieGraph: Understanding and Detecting First-Party Tracking Cookies", pp. 3490–3504. Association for Computing Machinery, New York, NY, USA. (DOI) (Link)
- [2]
- Lee, Jiyeon; Kim, Hayeon; Park, Junghwan; Shin, Insik; Son, Sooel (2018): "Pride and Prejudice in Progressive Web Apps: Abusing Native App-like Features in Web Applications", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)
- [3]
- Karami, Soroush; Ilia, Panagiotis; Polakis, Jason (2021): "Awakening the Web's Sleeper Agents: Misusing Service Workers for Privacy Leakage", in: Proceedings of the Network and Distributed System Security Symposium. (Link)
- [4]
- Liu, Xiaoyin; Li, Wenzhi; Hou, Qinsheng; Yang, Shishuai; Ying, Lingyun; Diao, Wenrui; Li, Yanan; Guo, Shanqing; Duan, Haixin (2024): "From Promises to Practice: Evaluating the Private Browsing Modes of Android Browser Apps", in: Proceedings of the ACM Web Conference. (DOI)
- [5]
- Ali, Mir Masood; Chitale, Binoy; Ghasemisharif, Mohammad; Kanich, Chris; Nikiforakis, Nick; Polakis, Jason (2023): "Navigating Murky Waters: Automated Browser Feature Testing for Uncovering Tracking Vectors", in: Proceedings of the Network and Distributed System Security Symposium. (Link)
- [6]
- Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)
- [7]
- Aggarwal, Gaurav; Bursztein, Elie; Jackson, Collin; Boneh, Dan (2010): "An Analysis of Private Browsing Modes in Modern Browsers", in: Proceedings of the USENIX Security Symposium. (Link)
