User Tools

Site Tools


provenance:privacy:javascript

Provenance: privacy:javascript

Working notes behind javascript — every query, its population and its denominator, the report script and its unedited output, the folds and their residue, the quotes that were checked, 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.

Partly reconstructed. The content page was written on 2026-08-06/07, before this site had a provenance convention. This page was written on 2026-08-12, during the refresh to the extended corpus. Sections marked recorded were produced by the 2026-08-12 run. Sections marked reconstructed were rebuilt from the report script, its output and the page text. The page's Methods, and Which Ones Are Current table, the tool maintenance-status table and the two 2025 crawl-design results were researched and verified outside the corpus by the original run and were not re-verified here.

1. What this page is backing

Item Value
Content page javascript
Report script scripts/report_javascript.mjs (–wiki for DokuWiki tables, –list for the full paper list)
Population rule and folds scripts/js_fold.mjs
Quote verification scripts/quote_check.mjs –classification javascript
Data data/extract/run1/extractions.jsonl, 5,859 papers, 7 venues, 2010–2026
Refreshed 2026-08-12

2. The population, which is this page's hardest problem

Reconstructed (rule), recorded (counts). Neither obvious schema handle finds this literature, so membership is built from three independent signals and a paper joins if it measures the web platform and matches at least one:

  1. a detection[] tuple whose phenomenon — not merely its technique — names a script, JavaScript, WebAssembly, eval, SRI or a browser-API surface;
  2. a classification[] tuple whose target names a script;
  3. the paper used or produced a JavaScript-specific analysis tool, from an ordered family list.

Requiring only the technique would admit every paper that used a line of JavaScript to run an experiment. Three tool families appear in the tool table but are deliberately not membership signals, because their non-analysis use was measured rather than assumed: OpenWPM (drags in an IPv6-scanning study, a QUIC website-fingerprinting paper and an HSTS study using it as a plain crawler), Emscripten (papers that compile to WebAssembly), SpiderMonkey (RIDL, where the engine is the victim). Three further papers — Spectre, Fallout, RIDL — are removed by hand with the reason recorded inline in js_fold.mjs.

Population Old (4,322 corpus) New (5,859 corpus)
JS-analysis papers 160 206
…with ≥1 classification tuple 153 198
…that ran a crawl 128 (80.0%) 165 (80.1%)
…that recorded a crawl configuration 126 163
comparison column: all papers with a crawl configuration 829 1,080

Signal combinations, which is how to see whether the rule is load-bearing:

Signal combination Old New
classification only 43 (26.9%) 57 (27.7%)
detection only 42 (26.3%) 53 (25.7%)
detection + classification 23 (14.4%) 30 (14.6%)
tool only 21 (13.1%) 26 (12.6%)
tool + detection + classification 12 (7.5%) 19 (9.2%)
tool + detection 11 (6.9%) 13 (6.3%)
tool + classification 8 (5.0%) 8 (3.9%)

The distribution is essentially unchanged, which is the useful thing to know: the population rule scaled with the corpus rather than drifting. Roughly a quarter of the population is admitted by each single signal, so dropping any one of the three would lose a quarter of the field.

3. Running it

cd /workspace/artifacts/wiki
node scripts/report_javascript.mjs             # every figure, both fold residues
node scripts/report_javascript.mjs --wiki
node scripts/report_javascript.mjs --list      # the full 206-paper list
node scripts/quote_check.mjs --classification javascript --show 13
node scripts/check_page_numbers.mjs \
  pages/privacy_javascript.txt out/new/report_javascript.txt \
  '===== What This Literature Actually Is =====' '===== Open Questions ====='

check_page_numbers.mjs left 22 figures unaccounted. All 22 are non-corpus figures and none was changed by the refresh: F1 scores and feature counts quoted from AdFlush, Zafar et al.'s 20.6% and 92.8%, Lauinger et al.'s 87.7% / 46.5% / 37.8% / 9.7%, the 77,423-domain denominator, arXiv identifiers, tool version numbers and commit dates, and 4,322 quoted as the old corpus size. This page has an unusually high count because roughly half of it is a guide to methods rather than a corpus report.

4. What the refresh changed

Recorded.

Figure Old New
Population 160 206
program-analysis tool users 959 → 215 web (22.4%) 1,385 → 299 web (21.6%)
code-or-binary-analysis 1,063 → 249 (23.4%) 1,484 → 347 (23.4%)
LLVM / Soot / IDA Pro / FlowDroid 66 / 61 / 36 / 34 101 / 81 / 62 / 48
Esprima, top JS parser in the corpus 15 23
Per 1,000, by period 23.5 / 45.0 / 41.3 / 33.9 27.4 / 44.2 / 42.4 / 34.8 / 24.5*
Tracking/advertising classification 25 (15.6%) 29 (14.1%)
Fingerprinting-script detection 19 (11.9%) 24 (11.7%)
Client-side vulnerabilities 12 (7.5%) 18 (8.7%)
Script performance, size, dead code 3 (1.9%) 8 (3.9%)
Unmapped detection tuples 45 65
Esprima (tool, in population) 16 (10.0%) 21 (10.2%)
OpenWPM (tool, in population) 17 (10.6%) 19 (9.2%)
Project Foxhound 2 (1.3%) 8 (3.9%)
PageGraph 4 (2.5%) 8 (3.9%)
Jalangi 1 4
Names no JS-analysis tool at all 91 of 160 (56.9%) 120 of 206 (58.3%)
heuristic-rules 80 (52.3%) 108 (54.5%)
dynamic-analysis 21 (13.7%) 33 (16.7%)
supervised-ml 26 (17.0%) 31 (15.7%)
llm 0 (enum never fired) 2 (1.0%)
Distinct ground-truth strings 278 351
Unmapped ground-truth tuples 52 80
Authors' own manual inspection 84 (54.9%) 102 (51.5%)
Filter list or tracker database 36 (23.5%) 44 (22.2%)
States some validation 115 (75.2%) 146 (73.7%)
States none anywhere 38 (24.8%) 52 (26.3%)
States headless 28 (22.2%) 31 (19.0%)
Artifact link, 2022–2024 46 of 59 (78.0%) vs corpus 64.7% 53 of 68 (77.9%) vs corpus 65.0%
Artifact link, 2025–2026* 27 of 29 (93.1%) vs corpus 76.5%
Assesses a law 13 (8.1%) vs corpus 6.1% 19 (9.2%) vs corpus 6.9%

Moved by more than a rounding step:

  • Project Foxhound 2 → 8 and PageGraph 4 → 8. This is the substantive finding of the refresh for this page, and it is unusual: the Methods table calls taint tracking and page-execution graphs “current” on the basis of work outside the corpus, and the extended corpus now independently shows those two instruments growing fastest inside it. A currency judgement that was an editorial call in August 2026 now has partial corpus support. The page says so.
  • Esprima overtook OpenWPM as the most-named tool in the population, 21 to 19. Small numbers; reported as a ranking.
  • The llm classification method fired for the first time, twice. Recorded on the page next to the existing, still-accurate finding that no peer-reviewed paper classifies web scripts as trackers with a language model. Two papers using an LLM for some script-classification task is not the same claim.
  • Per-1,000 density falls to 24.5 in 2025–2026, the lowest since 2010–2013. Almost certainly an artefact of the provisional years rather than a real collapse, and marked provisional in the table.
  • dynamic-analysis 13.7% → 16.7% and static-analysis 10.5% → 12.6%. classification.method agrees on only 58% of papers between runs, so neither is publishable as a change.

Not changed: the granularity discussion, the Methods, and Which Ones Are Current table, the ground-truth argument, the tool maintenance table, What to Report, and every citation.

5. Folds — the ones that did not age

Recorded. Unlike fp_fold.mjs (see fingerprinting), js_fold.mjs needed no changes. Both its residues grew roughly in proportion to the population:

Fold Old residue New residue Residue per population paper
Research family (detection.phenomenon) 45 tuples / 160 papers 65 / 206 0.28 → 0.32
Ground truth (groundTruthSource) 52 tuples / 153 papers 80 / 198 0.34 → 0.40

That is drift, not a break. It is worth saying why the two folds behaved so differently: fp_fold.mjs folds a subject (“what was fingerprinted”), and the 2025–2026 papers fingerprint genuinely new subjects — DPI boxes, LLMs, AR/VR apps. js_fold.mjs folds a research question and a label source, and those did not change: the field is still classifying trackers, malware and libraries, still using EasyList and its own eyes. A fold over subjects ages faster than a fold over methods. Whoever refreshes these pages next should check the subject-folds first.

Both residues are printed in full by report_javascript.mjs and are not reproduced here; they are long and one-per-paper.

5.1 Two bugs in the report script

  1. The last period bucket was (y) ⇒ y >= 2022, so it swallowed 2025–2026 and reported the 2022–2024 corpus size as 3,140 instead of 1,955. The same open-ended filter was used for the artifact-release comparison. Both split into 2022–2024 and a starred 2025–2026.
  2. “corpus-wide 6.1%” was a hardcoded string in the legal line. On the new corpus it is 6.9% (402 of 5,859), and the hardcoded version printed the old numerator's rate beside the new population — the most dangerous kind of stale number, because it appears in freshly-computed output. Replaced with the computed value.

The identical bucket bug was present in report_fingerprinting.mjs and report_ip_classification.mjs. It is the single most common defect found in this refresh: an open-ended last bucket is correct exactly once, and then silently wrong forever.

6. Quotes checked

Recorded, 2026-08-12.

$ node scripts/quote_check.mjs --classification javascript
66 quotes checked: 34 exact, 19 partial (>=60% of 5-word windows),
13 below threshold, 0 with no full text on disk.

Five of the 13 below-threshold quotes were read by hand against paper.cols.txt2013/USENIX/revolver, 2017/IMC/the-ad-wars, 2017/PETS/towards-seamless-tracking-free-web, 2011/CCS/fortifying-web-based-applications, 2012/USENIX/privilege-separation-in-html5-applications — and all five are present. The last is a good example of why the automated test cannot be trusted alone; the source reads:

…ify all calls to privileged APIs (i.e., calls The parent allows the child
XMLHttpRequest ac- to the chrome object) and list them in Figure 1. We be-
cess to only /sqlbuddy/<filename>.php URIs. lieve that our analysi…

The extraction's “we (conservatively) identify all calls to privileged APIs (i.e., calls to the chrome object)” is correct; the two columns interleave inside the parenthesis. The other 8 were not read.

Reconstructed: the original run recorded that “each number reproduced on this page was re-located in paper.cols.txt after whitespace normalisation”, which is a stronger claim than the one above and applies to the quoted prevalence figures rather than to the schema tuples. Which numbers is not recoverable. One specific check from that run is recorded and is worth repeating here because it is the page's best cautionary tale:

  • The PoPETs 2023 blanket-JS-blocking result was quoted from the paper's prose, which says “22% of functional requests and 76% of tracking requests remain”. The paper's Table 2 says tracking 1,175,033 → 265,101 (22.6% remaining) and functional 4,279,844 → 3,248,767 (75.9% remaining). The labels are transposed in the published paper. detection[].prevalence faithfully copied the prose, so no automated audit could catch it — only reading the table did. The page carries the corrected reading.

7. External sources

Reconstructed. Not re-verified on 2026-08-12. The page's non-corpus half is unusually large and unusually date-sensitive:

  • Every tool's maintenance status was checked against its own repository commit history on 2026-08-06 and each row carries that date. Several were declared “abandoned in practice” on that evidence (AdGraph, last commit 2019-09-16). These will rot; re-check before relying on them.
  • The LLM-absence finding — that no peer-reviewed paper classifies web scripts as trackers with a language model — was established by targeted search across PETS 2025/2026, USENIX Security 2025, NDSS 2025/2026, IMC 2025, TheWebConf 2025/2026, CCS 2025 and arXiv on 2026-08-06. The nearest hits (LLM-aided deobfuscation feeding a graph classifier; humanify, which only proposes identifier names) are cited as adjacent and explicitly not on-point. The extended corpus does not overturn this: the two llm classification tuples it added are script-classification tasks, not tracker classification, and the page distinguishes them.
  • The Manifest V3 timeline is from Chrome's own documentation, not a secondary source.
  • humanify was checked at v3.1.1 and the footnote records that the AST rewrite is done by oxc, not the model — a correction to the obvious reading of the project's own description.

Rejected: not recorded for the original run.

8. What could not be established

  • Whether the 8 unread below-threshold quotes check out. See §6.
  • Whether the per-1,000 decline is real. The series peaks at 44.2 in 2014–2017 and falls to 24.5 in 2025–2026, but the last point is provisional and the page's own explanation — the topic being absorbed into tracking and supply-chain papers that no longer call themselves JavaScript analysis — is an interpretation the extraction cannot test.
  • The false-positive tail of the 206. An e-voting client audit, a router-attack paper and a PHP injection-sink study are in the population and analyse JavaScript incidentally. They were left in and the page says so; –list prints them all so a reader can judge. Nobody has audited the list paper by paper on the new corpus.
  • Whether classification.method shares are worth publishing at all. 58% run-to-run agreement is the weakest field carrying a table on this page. It is labelled as a rough share, which is the most that can honestly be done with it.
  • ACSAC and EuroS&P are absent and a good deal of web-script security work lands there. Stated on the page.

10. Review pass, 2026-08-12

Recorded. The refresh was reviewed by a second model (Claude Fable 5), told explicitly that the summary it was given might not be exhaustive, with instructions to hunt stale numbers. It found a systematic defect, not a scatter of typos, and it is worth stating because it will recur on the next refresh:

  • check_page_numbers.mjs was run with a heading window — normally Use in Publications to the next section — so it audited only the corpus section. Every corpus figure repeated in a page's intro, tooling section, recommendations, footnotes, Related Pages or an embedded code block was outside the window and stayed at its 4,322-corpus value. Across the six pages 29 such figures survived the first pass.
  • The matcher was substring, not word-boundary, so report.includes('59') was satisfied by 11.59 bits. One genuinely stale figure sat inside a checked window and passed for that reason.

Both are fixed in scripts/check_page_numbers.mjs: matching is now anchored with lookarounds, ISO dates and URLs are stripped before scanning, –code opts into scanning <file> blocks, and omitting the heading markers checks the whole page. Run it windowed and whole-page. The whole-page run is noisy — a page's non-corpus half is full of figures quoted from other papers — so read its output rather than expecting it to exit clean. Fixed on this page's content page as a result — and one of them is the most instructive defect in the whole refresh:

  • The embedded <file javascript js_fold.mjs> block still quoted the 4,322-corpus countsprogram-analysis on 959 papers, code-or-binary-analysis on 1,063, LLVM 66, Soot 61, IDA Pro 36, FlowDroid 34, angr 28, Esprima 15 — two screens below the page's own table saying 1,385 / 1,484 / 101 / 81 / 62 / 48 / 39 / 23. The published, downloadable source contradicted the prose. check_page_numbers.mjs strips <file> blocks and so could never have caught it; it now takes –code. Fixed in both scripts/js_fold.mjs and the embedded copy, and the two were diffed afterwards.
  • Related-Pages shares 42.4% → 39.8% and 28.6% → 27.6%.
  • “the privacy reader's own family is the largest but is barely a quarter of the field” was wrong against its own table: the largest single family is 29 of 206 = 14.1%. Rewritten to name the two families that together make 53 of 206 = 25.7%, which is what “barely a quarter” was always describing.

11. Run log

Date 2026-08-12
Corpus at the time data/extract/run1, 5,859 papers, 2010–2026, IEEE S&P complete at 780/780
Model Claude Opus 5, no sub-agents used for this page
Scope Mechanical re-derivation. One paragraph of new prose, on Foxhound and PageGraph growth, because the refresh turned an editorial currency judgement into a partly measured one.
Script changes report_javascript.mjs (bucket bug, hardcoded 6.1%, split artifact comparison), js_fold.mjs (comments only — the ground-truth string count, and, after review, the module docstring's stale corpus counts; see §10)
Caveats deleted “IEEE S&P is only 43% retrieved” — 780 of 780 selected papers are now retrieved. “This corpus ends in 2024.”
Not deferred, but worth flagging The llm row is 2 papers. If it is still 2 on a complete 2026, it means nothing; if it is 15, this page's Methods table needs a new row.
Review Reviewed by Claude Fable 5 on 2026-08-12 with the instruction that the summary might not be exhaustive. It found the windowed-guard defect in §10 and 3 stale figures on this page plus the embedded js_fold.mjs docstring. All fixes were applied and re-saved the same day.

← back to the content page · corpus-level provenance

provenance/privacy/javascript.txt · Last modified: by karel.kubicek.claude

Except where otherwise noted, content on this wiki is licensed under the following license: CC BY-NC-SA 4.0
CC BY-NC-SA 4.0 Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki