| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| privacy:requests [2025/01/08 13:58] – Added link decorators section karelkubicek | privacy:requests [2026/08/29 13:36] (current) – Replace the last literal corpus figure inherited from the carve-out with a pointer to the section that maintains it. Authored by Claude karel.kubicek.claude |
|---|
| A common task in web privacy measurements is to determine which web requests correspond to the benign loading of required web resources and which are used to track users. There are two main methods for such classification: matching requests against crowd-sourced lists (typically used in ad-blocking or tracking protection extensions) or using machine learning (**ML**) to classify the requests based on their context and request URL. | A common task in web privacy measurements is to determine which web requests correspond to the benign loading of required web resources and which are used to track users. There are two main methods for such classification: matching requests against crowd-sourced lists (typically used in ad-blocking or tracking protection extensions) or using machine learning (**ML**) to classify the requests based on their context and request URL. |
| |
| This page is dedicated to the classification of web requests and partially DOM elements on the loaded page. For classification of other resources, such as [[Privacy:Cookies|cookies]], [[Privacy:JavaScript|JavaScript code]], or [[Privacy:Fingerprinting|fingerprinting]], navigate to the specific pages. | This page is dedicated to the classification of web requests and partially DOM elements on the loaded page. For classification of other resources, such as [[Privacy:Cookies|cookies]], [[Privacy:JavaScript|JavaScript code]], or [[Privacy:Fingerprinting|fingerprinting]], navigate to the specific pages. What you drive the browser with is [[Programming:Crawler|a separate decision]], and it constrains this one: a classifier that needs the initiator chain or the script call stack needs a crawler that records them. |
| |
| ===== Block Lists ===== | <WRAP important> |
| | **The one thing to understand before you start: in this field the filter list is both the instrument and the ground truth, and almost nobody separates the two.** Of the 14 papers in [[#Use in Publications|this page's population]] that carry a learned request classifier, **8 take their labels from a filter list** — including every reference baseline the field compares against (AdGraph, WebGraph, Khaleesi, WTAGRAPH, AdFlush, Duumviri). So "our classifier reaches 98% accuracy" usually means "our classifier agrees with EasyList 98% of the time", and the residual is reported as error rather than as discovery. |
| |
| ==== Crowd-Sourced and Outdated ==== | We now know roughly what that costs. Calzavara et al. {[calzavara2026_syntactic]} (PoPETs 2026) ran syntactic filter-list matching and dynamic taint tracking over the same crawl and compared them request by request: of the 40,605 tracking requests found, syntactic matching found 33,584 and taint tracking 23,109, but **only 16,088 were found by both**. They then re-tested every one of those matches automatically, with a **canary**: replace the identifier in client-side storage with a fresh value, revisit the page, and see whether the new value shows up in a request matching the same template. If it does the match is confirmed; if the old value is still there instead, it is refuted. The estimate that comes out is **16%–19% likely false positives among the syntactic matches**, rising to **27%–30%** among the requests only syntactic matching flagged, against **4%–7%** for the requests taint tracking found — and **7,021 requests, around 17% of the dataset, were found by taint tracking alone**. Treat a filter-list hit as a noisy label with error bars in the high teens, not as a definition — and say in your paper that you did. **That said, this is one study, one taint-tracking browser, 7,614 sites**; nobody has repeated it, and [[#Open Questions]] says so. |
| The main principle of block lists is their crowd-sourced nature. For instance, the [[https://github.com/easylist/easylist|EasyList repository]] has almost 300 contributors, over 200k commits, and more than 7k resolved issues. This has several implications: | </WRAP> |
| |
| * Widespread advertisers and trackers have well-defined and up-to-date rules, while the long tail of tracking companies might not be covered well. | ===== What to Read First ===== |
| * Adding rules is much more common than deleting them. Up to 90% of the resource-blocking rules in EasyList provide no benefit to users in common browsing scenarios {[snyder2020_who]}. | |
| * There is a cat-and-mouse game between list maintainers and the advertising industry. Some rules (e.g., [[https://www.engadget.com/inside-the-arms-race-between-youtube-and-ad-blockers-140031824.html|YouTube's war on ad blocking]]) are short-lived, making it necessary to use up-to-date lists. | |
| |
| ==== Blocking Specific Resources ==== | * **[[https://arxiv.org/abs/2506.14057|SoK: Advances and Open Problems in Web Tracking]]** {[vekaria2025_soktracking]} — a systematisation by **fourteen** of the field's authors, and the fastest orientation to where request classification sits in the wider tracking literature. Its §V-C1 gives the same three-limitation account of filter lists this page gives (small maintainer community, accumulated dead rules, static so evadable) and then names the ML lineage: AutoFR, AdGraph, WebGraph, WTAGraph, and PageGraph as the shipped implementation. **It is still a preprint**: only v1 exists (16 June 2025), and the version exhibited as a poster at IEEE S&P 2026 labels itself "Preprint".((Checked 2026-08-12: ''arxiv.org/abs/2506.14057'' lists only ''[v1] Mon, 16 Jun 2025''; v2 and v3 return HTTP 404. The extended version is at [[https://github.com/privacysandstorm/sok-advances-open-problems-web-tracking|github.com/privacysandstorm/sok-advances-open-problems-web-tracking]]. Do not trust the listing page's own count: its PDF link reads "by Yash Vekaria (1) and 36 other authors", because arXiv's author metadata for this paper runs the affiliation list into the author field. The paper itself names Vekaria, Beugin, Munir, Acar, Bielova, Englehardt, Iqbal, Kapravelos, Laperdrix, Nikiforakis, Polakis, Roesner, Shafiq and Zimmeck — fourteen.)) Check for a venue version before you cite it as published. |
| | * **SoK: After Decades of Web Tracker Detection, What's Next?** {[rieder2026_sok]}, IEEE S&P 2026 — a meta-study specifically of tracker //detectors//, which is the classifier lineage this page is about. |
| | * Then read in this order, because each one answers the previous one's complaint: filter lists as measured dead weight {[snyder2020_who]} → what they miss {[fouad2020_missed]} → the graph lineage {[iqbal2020_adgraph]}, {[siby2022_webgraph]} → mixed resources {[amjad2021_trackersift]} → the deployable classifier {[lee2024_adflush]} → labels that at least come with a breakage check {[shuang2025_duumviri]} → how wrong the list was all along {[calzavara2026_syntactic]}. |
| |
| Rules can prevent actions from happening (useful for protecting user privacy), either by blocking entire domains or specific requests based on their paths. Alternatively, rules can be applied after loading a resource (described by a CSS selector) to prevent its rendering, which is more useful for blocking advertisements or annoying elements. | ===== Pick the Unit Before You Pick the Method ===== |
| |
| ==== Existing Lists ==== | "Which requests are tracking" hides a choice of unit, and the units are not interchangeable. Papers that appear to disagree about tracking prevalence are often measuring different rows of this table. |
| |
| * DNS-blocking lists | ^ Unit ^ What you get ^ What it costs ^ |
| * [[https://web.archive.org/web/20241231165520/https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters|AdBlock-syntax]] filters. The most established are [[https://easylist.to/index.html|EasyList filters]]: | | **eTLD+1 / domain** | The cheapest unit, and the only one a hosts-file or DNS blocklist can give you. Comparable across papers | Cannot distinguish ''cdn.example.com/jquery.js'' from ''cdn.example.com/track.gif''; CNAME cloaking and first-party proxying defeat it {[dimova2021cname]} | |
| * **EasyList**: Blocks advertisements except for self-promotion (first-party ads such as featured articles). See the full [[https://easylist.to/pages/policy.html|policy]]. | | **entity / company** | The unit the //question// usually wants: ''google.com'', ''googleapis.com'' and ''doubleclick.net'' are one organisation, so an eTLD+1 "third party" label is wrong for same-org domains | Needs an entity map. Disconnect's ''entities.json'' and DuckDuckGo Tracker Radar's entity-to-domain map are the two the field uses, and they disagree; whichever you pick, name it | |
| * **EasyPrivacy**: Aims to block tracking and improve user privacy. The policy is documented at the bottom of [[https://easylist.to/pages/policy.html|this page]]. It supports four categories: | | **request URL** | What Adblock-syntax lists actually match on, with resource type and party as modifiers | A tracker that rotates paths or moves to a first-party subdomain escapes; blocked replica ad domains survived a mean 410.5 days before a rule appeared — see below | |
| * Generic blocks: Common URL/tracking filter patterns used by 1st- and 3rd-parties. | | **script / resource** | Attributes the request to the code that made it | ~13.4% of scripts are //mixed// — they do tracking and functionality in the same file {[amjad2024_notjs]} | |
| * 1st-party tracking: Self-hosted trackers and CNAME trackers. | | **request chain** | Catches trackers that only appear downstream of a redirect | Needs the initiator chain recorded; roughly one third of requests in a crawl are in a chain {[iqbal2022_khaleesi]} | |
| * 3rd-party tracking: Hosted by another provider hosting a tracking script but not actually a tracking company. | | **function / method** | The finest granularity anyone has published | Needs a patched browser, and is a [[Privacy:JavaScript|JavaScript]] question as much as a request one | |
| * Tracking servers: Servers with the sole purpose of tracking/analyzing users are blocked at the URL level. | | **URL parameter** | Catches identifiers passed in link decoration that survive third-party cookie blocking | A different classifier and a different list — see [[#Link Decoration and Tracking Parameters]] | |
| * [[https://easylist.to/pages/other-supplementary-filter-lists-and-easylist-variants.html|Country-specific lists]]: Mostly block advertising. | |
| * Technology-specific lists: | |
| * Cookie notices: To detect cookie notices, consider the following options: | |
| * **EasyList Cookie List**: A CSS selector list that is the most generic and up-to-date. | |
| * **I (Still) Don't Care About Cookies**: In addition to removing DOM elements descibed by EasyList Cookie List, this extension performs simple actions like clicking "accept all" or "reject all" when available. It is useful for passing consent notices during crawling when the specific consent action is unimportant. The rules are available [[https://github.com/OhMyGuus/I-Still-Dont-Care-About-Cookies/blob/master/src/data/js/5_clickHandler.js|here]]. | |
| * **Consent-O-Matic**: If you care about consent actions (accepting or rejecting consent), consider the rules of the [[https://github.com/cavi-au/Consent-O-Matic|Consent-O-Matic]] extension. Forks by [[https://github.com/duckduckgo/autoconsent|DuckDuckGo]] (seems to be the most active) and [[https://github.com/mozilla/cookie-banner-rules-list|Mozilla]] are also available. These work with specific consent providers (Consent Management Platforms, **CMPs**). | |
| |
| ==== Programming: Using Lists ==== | **Mixed resources are the normal case, not the tail.** TrackerSift {[amjad2021_trackersift]} measured how far up the granularity ladder you have to go before a resource is purely one or the other: more than **17% of domains, 48% of hostnames, 6% of scripts and 9% of methods** in their crawls combine tracking and functional behaviour. Blocking at the hostname level therefore breaks things, and 9 of their 10 manually inspected sites showed major or minor breakage when mixed scripts were blocked. Whatever unit you pick, say what you did with the mixed cases; "we blocked the domain" is a decision with a measurable cost. |
| |
| Block lists use regular expressions with custom syntax to decide which resources to block. Consider the following parsing libraries: | ===== Methods, and Which Ones Are Current ===== |
| |
| * [[https://github.com/englehardt/abp-blocklist-parser|abp-blocklist-parser]]: | <WRAP important> |
| * Can decide whether to block requests, images, etc. | A ranking of what the 2010–2026 literature //did// is a fact about the literature, not advice about what to do now. The table below dates each method and states its status as of **2026-08-12**. Our corpus reaches 2026 but its 2025–2026 venue-years are provisional (CCS and IMC 2026 have not been held; IEEE S&P and WWW 2026 are incompletely selected), so //current// rows were checked against work outside the corpus as well. |
| * [[https://github.com/scrapinghub/adblockparser|adblockparser]]: | </WRAP> |
| * An older parser with some [[https://github.com/scrapinghub/adblockparser#limitations|limitations]]. | |
| | ^ Era ^ Method ^ Representative work ^ Status in 2026 ^ |
| | | 2010– | **Adblock-syntax filter lists**, applied live or in post-processing | EasyList, EasyPrivacy, Disconnect | **Current, and still the default.** It is more than half again as common as anything else in the corpus section below. Not because it is best but because it is comparable, free and reviewable | |
| | | 2015–2019 | Supervised classifiers on **URL and content features** | One-class learning on tracker URLs {[ikram2017_seamless]} | **Superseded.** Content features are attacker-controlled; WebGraph's evasion experiment is the demonstration | |
| | | 2017–2021 | **Anti-adblock and circumvention detection** as its own task | The ad wars {[iqbal2017_wars]}, anti-adblock detection {[mughees2017_detecting]}, CV-Inspector {[le2021_inspector]} | **Alive but niche.** CV-Inspector reached 93% accuracy on sites that successfully circumvent adblockers, and found that over a third of sites with relevant rules in the Anti-Circumvention Filter List still circumvented | |
| | | 2020–2022 | **Graph representations of page execution**, ML-classified | AdGraph {[iqbal2020_adgraph]} (95.33% accuracy), WebGraph {[siby2022_webgraph]} (94.32% accuracy), WTAGRAPH {[yang2022_wtagraph]} (97.90%) | **The reference baselines** — every later paper compares against them. Treat them as baselines to beat, not as tools to install | |
| | | 2020–2022 | **Request chains** as the unit, sequential ML | Khaleesi {[iqbal2022_khaleesi]} (94.07% on a later crawl) | **Still a cited baseline.** It is not a page-execution graph; do not lump it with AdGraph | |
| | | 2021–2023 | **Rule generation** rather than rule matching: learn the filter rules themselves | AutoFR {[le2023_autofr]}, regional list generation {[sjosten2020_filter]} | **Current, and under-used in measurement.** AutoFR's generated rules blocked 86% of ads against EasyList's 87%, within its breakage threshold | |
| | | 2021 | **Surrogate replacement** instead of blocking, to avoid breakage | SugarCoat {[smith2021_sugarcoat]} | **Current**, and a Brave collaboration rather than a research prototype.((Brave's own privacy-updates index carries it as post #12, 18 November 2021: "Brave and UC San Diego announce SugarCoat, a new solution to strengthen the protection of Web users' privacy while not breaking websites… the result of a year-long research collaboration". Checked 2026-08-12 at [[https://brave.com/privacy-updates/|brave.com/privacy-updates]]. The per-post URL that used to hold it now 404s, so this is the announcement, not a claim about which Brave version ships it today.)) Mean breakage rating 1.03 (normal) versus 2.86 when the same scripts were blocked outright | |
| | | 2023–2024 | **Deployability as the objective**: small feature sets, no content features | AdFlush {[lee2024_adflush]} | **Current.** F1 0.98 against AdGraph 0.93, WebGraph 0.90, WTAGraph 0.84; F1 stayed above 0.9789 for five and a half months without retraining | |
| | | 2024 | **Function granularity** with dynamic calling context | NoT.js {[amjad2024_notjs]} | **Current**, and mostly a [[Privacy:JavaScript|JavaScript]] method | |
| | | 2024 | **Link-decoration classification** — the parameter, not the request | PURL {[shaoor2024purl]} | **Current, and the growth area.** See [[#Link Decoration and Tracking Parameters]] | |
| | | 2025 | **Response headers** rather than request features, for cross-browser transfer | Beyond the Request {[rieder2025_beyond]} | **Current**, and the honest negative result in it matters: classifiers trained on Chrome and Firefox degraded substantially on Brave | |
| | | 2025 | **Differential features plus a breakage detector** — block the request field, measure how the page changes | Duumviri {[shuang2025_duumviri]} | **Current, and the most interesting direction.** Its features are behavioural rather than drawn from the labelled artefact, and a separate breakage detector catches functional requests the lists mislabel. It reproduces filter-list labels at 97.44% and found 22 previously unreported trackers. Note it still //trains// on EasyList and EasyPrivacy labels | |
| | | 2026 | **Taint tracking as a cross-check on syntactic matching** | Calzavara et al. {[calzavara2026_syntactic]} | **Read this before choosing between the two.** It is the measurement of how much your filter list is wrong by | |
| | | 2026 | **LLM-assisted annotation** feeding a graph classifier | TGNN {[xiong2026_tgnn]} | **Emerging.** Exactly one paper in this corpus classifies web requests with an LLM, and it uses the model to //label training data// (F1 98.17% against expert labels), not to classify at inference | |
| | |
| | ==== What is genuinely superseded ==== |
| | |
| | * **Matching on the third-party hostname alone.** CNAME cloaking {[dimova2021cname]}, first-party subdomains and CDN hosting all defeat it, and Lin et al. {[lin2022_investigating]} quantified the churn: among 252,601 domains seen while crawling 50,000 sites they found **1,748 replica ad domains**, of which 35.9% worked by changing subdomains and 17.4% by moving to first-party subdomains. The 1,096 that lists did eventually block survived a **mean 410.5 days** (median 195.5) before a rule appeared. |
| | * **URL and page-content features in a learned classifier.** WebGraph {[siby2022_webgraph]} showed the point directly: a URL-mutating adversary succeeded against AdGraph **96.62%** of the time once first-party collusion was allowed, and against WebGraph's content-free features only **8.34%**. |
| | * **Perceptual ad blocking as a robust method.** Tramèr et al. {[tramer2019_adversarial]} broke every perceptual ad blocker they examined; it is worth reading as the reason nobody builds on it. |
| | * **Treating a filter-list hit as the definition of tracking.** See the box at the top. |
| | |
| | ==== What the corpus cannot tell you ==== |
| | |
| | **LLM classification of web requests is, as of 2026-08-12, essentially absent from the peer-reviewed literature.** One paper in these seven venues, TGNN {[xiong2026_tgnn]} (TheWebConf 2026), carries an ''llm'' method on a ''web-request'' classification tuple, and it uses the model to //annotate training data// rather than to classify at inference. A targeted search outside the corpus — arXiv, EuroS&P, ACSAC, RAID, AsiaCCS and WPES, 2025–2026 — found no peer-reviewed paper that prompts or fine-tunes a language model to decide whether an HTTP request is tracking. Industry is ahead of the literature here and says so: AdGuard demonstrated a prototype at the Ad-Filtering Dev Summit in October 2025 that asks a model per resource instead of consulting a list, and reported latency and cost as the blockers.((AdGuard, [[https://adguard.com/en/blog/beyond-filter-lists-rethinking-ad-blocking-with-llms.html|"Beyond Filter Lists: Rethinking Ad Blocking with LLMs"]], published 2025-11-18, describing a talk given at the summit that October; checked 2026-08-12. A vendor blog post about a Chrome-extension prototype, not a peer-reviewed evaluation — cited here as evidence that the idea is being tried, not as a result.)) If you are planning an LLM-based request classifier you are not late — but you have no baseline to cite, so budget for building one, and for the reviewer question about cost, reproducibility and prompt drift that this page cannot answer for you. |
| | |
| | **And one 2026 paper is missing from the tables below by construction.** AdVersa {[lim2026_adversa]} (TheWebConf 2026) reports F1 **98.23%**, generalisation to unseen domains at 91.47% F1, and robustness where prior systems were evaded 57–92% of the time. TheWebConf 2026 is one of the incompletely-selected venue-years, so it is absent from every corpus figure on this page even though it is squarely in scope. Its own abstract frames it as embedding-based rather than LLM-based; treat it as the likeliest successor to the AdGraph/WebGraph line and **not** as the missing LLM baseline. Its figures here are the paper's own, taken from its abstract and Crossref record; nobody on this page has read it critically. |
| | |
| | ===== Block Lists ===== |
| | |
| | Matching a request against an Adblock-syntax filter list is what **57.0%** of the papers below do, and it is still the default. What it means to do that well — which lists exist and which are dead, how to record the exact version and commit you matched against, which engine to use, what a rule needs from your crawl in order to be evaluated at all, what the list misses and where, and why "on the list" is a definition rather than a finding — is one topic and it now has its own page: |
| | |
| | * **[[Programming:Filter Lists|Filter lists]]** — the list as instrument and as ground truth. |
| | |
| | The three things from it you cannot skip while reading this page: |
| |
| The advantage of these libraries is that they can classify which resources would have been blocked in post-processing. You can run a crawl allowing all resources and later use the filters to analyze the data. | * **A rule is evaluated against a request //in context//.** ''$third-party'', ''$domain='', the resource-type options and ''@@'' exception rules all need the initiator URL, the resource type and the redirect chain. A crawl that logged only request URLs cannot be post-processed with a list, and it fails silently rather than erroring. |
| | * **The list is a moving target.** EasyList publishes a ''Version:'' and a ''Commit:'' in its own header and changes several times an hour; of the corpus papers naming a list as a tool, **four** record something that identifies the rules they matched against ([[Programming:Filter Lists#Which version|the count and its denominator]]). |
| | * **A filter-list hit is a noisy label**, estimated at **16%–19% false positives** {[calzavara2026_syntactic]}, with the false negatives measured repeatedly and separately — 25.22% {[fouad2020_missed]}, 34.5% {[lee2023_track]}, and much worse off the desktop web. |
| |
| If you only need CSS selector filters during a crawl, your crawling library likely supports them natively. For example, in Selenium, you can use ''driver.find_element(By.CSS_SELECTOR, "img#tracker")''. | |
| |
| ===== ML Classification ===== | ===== ML Classification ===== |
| |
| While ad-blocking lists are used by up to a billion users, machine-learning-based blocking has not been widely adopted.((A notable ML-based browser extension was Privacy Badger, which used "local learning" to detect tracking. [[https://www.eff.org/deeplinks/2020/10/privacy-badger-changing-protect-you-better|This feature was later disabled to prevent fingerprinting]].)) There are several reasons for this: | Filter lists ship to users; learned classifiers, with one partial exception, do not. Three reasons, and all three matter for how you read the results below: |
| |
| * Using ML to dynamically decide whether to block a resource might make the browser fingerprintable. | * **A model that decides at runtime is a fingerprinting surface.** Privacy Badger's "local learning" was removed for exactly this reason.((EFF, [[https://www.eff.org/deeplinks/2020/10/privacy-badger-changing-protect-you-better|"Privacy Badger Is Changing to Protect You Better"]], October 2020.)) |
| * Adversarial machine-learning methods suggest that if ML blocking becomes popular, automated methods to evade detection will emerge. | * **Evasion is not hypothetical.** Tramèr et al. {[tramer2019_adversarial]} broke perceptual ad blocking outright, and AdGraph, WebGraph, Khaleesi and WTAGRAPH all report their own evasion rates — one of them, AdGraph, at 96.62%. |
| * Blocking content based on ML increases the chances of breaking websites, especially in non-reproducible ways. | * **Breaking a site in a way nobody can reproduce is worse than missing a tracker**, and a model gives you no rule to point at when a user complains. |
| |
| However, these challenges do not limit the application of ML-based detection in research. Several excellent publications have developed robust ML pipelines to detect advertising and privacy-intrusive resources, making them worth considering. | None of that stops you using a learned classifier as a //measurement// instrument, which is what this section is for. **But read the three subsections below as the field's historical baselines, not as recommendations**: the systems this page calls current are in [[#What Came After, and Why It Matters]]. |
| | |
| | <WRAP important> |
| | **These are baselines, not tools.** Every model below was trained on one crawl of one browser from one vantage point, against filter-list labels of one vintage. Beyond the Request {[rieder2025_beyond]} is the paper to read on what that costs: its classifiers reached ROC-AUC, AUPRC and F1 above 0.93 on Chrome and Firefox and degraded substantially on **Brave** — the same task, a different browser. If you download a published model and apply it to your crawl, you have changed the distribution and you owe the reviewer a validation on your own data. |
| | </WRAP> |
| |
| ==== AdGraph ==== | ==== AdGraph ==== |
| |
| **AdGraph: A Graph-Based Approach to Ad and Tracker Blocking** {[iqbal2020_adgraph]} uses ML classification based on EasyList lists. It constructs a graph structure of web elements, network requests, and JavaScript execution for feature extraction. Example features include graph size, node degree, request length, domain party, and the presence of advertising keywords in requests. A random forest model achieves performance above 90%, as shown below: | **AdGraph: A Graph-Based Approach to Ad and Tracker Blocking** {[iqbal2020_adgraph]} uses ML classification based on EasyList lists. It constructs a graph structure of web elements, network requests, and JavaScript execution for feature extraction. Example features include graph size, node degree, request length, domain party, and the presence of advertising keywords in requests. A random forest model achieves **95.33% accuracy, 89.1% precision and 86.6% recall** against labels derived from eight crowdsourced filter lists, as shown below. Its breakage was on par with the lists themselves: no breakage on 85.0% of sites against the lists' 88.6%, major breakage on 5.9% against 6.4%. |
| |
| <WRAP center box> | <WRAP center box> |
| </WRAP> | </WRAP> |
| |
| [[https://github.com/uiowa-irl/AdGraph|Repository with instrumented crawler]] | [[https://github.com/uiowa-irl/AdGraph|Repository with instrumented crawler]]. Its production successor is Brave's [[Programming:Crawler:PageGraph|PageGraph]], which is the practical way to get this representation today. |
| |
| ==== WebGraph ==== | ==== WebGraph ==== |
| |
| **WebGraph: Capturing Advertising and Tracking Information Flows for Robust Blocking** {[siby2022_webgraph]} is a follow-up to AdGraph. It improves feature processing to address adversarial ML methods, removes dependency on modifiable content features, and enhances overall performance. | **WebGraph: Capturing Advertising and Tracking Information Flows for Robust Blocking** {[siby2022_webgraph]} is a follow-up to AdGraph. It improves feature processing to address adversarial ML methods, removes dependency on modifiable content features, and enhances overall performance: **94.32 ± 0.27% accuracy** with content features removed, and the robustness result that justifies the design — a URL-mutating adversary with first-party collusion succeeded **96.62 ± 0.37%** of the time against AdGraph and **8.34 ± 0.66%** against WebGraph. |
| |
| [[https://github.com/spring-epfl/WebGraph|Repository with trained model and pipeline]] | [[https://github.com/spring-epfl/WebGraph|Repository with trained model and pipeline]] |
| ==== Khaleesi ==== | ==== Khaleesi ==== |
| |
| **Khaleesi: Breaker of Advertising and Tracking Request Chains** {[iqbal2022_khaleesi]} also extends AdGraph. Here is a [[https://github.com/uiowa-irl/Khaleesi|repository with trained model and pipeline]]. | **Khaleesi: Breaker of Advertising and Tracking Request Chains** {[iqbal2022_khaleesi]} also extends AdGraph, but changes the unit: it classifies **request chains**, which accounted for about one third of all requests in its crawls, reaching 94.07% accuracy on a later dataset than it was trained on. Here is a [[https://github.com/uiowa-irl/Khaleesi|repository with trained model and pipeline]]. |
| |
| Additionally, it offers a [[https://github.com/uiowa-irl/Khaleesi?tab=readme-ov-file#browser-extension|Firefox extension]] that blocks advertising chains. While not directly suitable for crawls (the current implementation blocks requests), you can disable the functionality [[https://github.com/uiowa-irl/Khaleesi/blob/main/browser_extension/background/background.js#L52|here]] and collect logs to classify ads. | Additionally, it offers a [[https://github.com/uiowa-irl/Khaleesi?tab=readme-ov-file#browser-extension|Firefox extension]] that blocks advertising chains. While not directly suitable for crawls (the current implementation blocks requests), you can disable the functionality by removing the ''return { cancel: true }'' at [[https://github.com/uiowa-irl/Khaleesi/blob/main/browser_extension/background/background.js#L51-L54|background.js lines 51–54]] (checked 2026-08-12: line 52 is the log, 53 is the cancel) and collect logs to classify ads instead. |
| |
| ==== Classification of Link Decorators ==== | ==== What Came After, and Why It Matters ==== |
| |
| TODO add: | ^ System ^ Unit and signal ^ Headline result ^ Why you would use it ^ |
| | | WTAGRAPH {[yang2022_wtagraph]}, IEEE S&P 2022 | Graph neural network over the whole page graph | 97.90% accuracy; 266 ms per page; evasion 0.22–3.11% | The GNN formulation of the same idea; a baseline AdFlush beats | |
| | | Net-track {[lee2023_track]}, TheWebConf 2023 | **Packet metadata only** — no browser instrumentation | 94.02% accuracy; still above 93% on partial traces | The only option when you cannot instrument the client at all (middlebox, router, encrypted DNS setting) | |
| | | AdFlush {[lee2024_adflush]}, TheWebConf 2024 | 27 features selected from 883, no content features | F1 0.98 vs AdGraph 0.93 / WebGraph 0.90 / WTAGraph 0.84; F1 > 0.9789 over five and a half months without retraining; F1 > 0.93 on all 14 HTTP request types | **The strongest current baseline**, and the one that reports longitudinal stability | |
| | | Beyond the Request {[rieder2025_beyond]}, PETS 2025 | **HTTP response headers**, imbalanced-setting evaluation | ROC-AUC, AUPRC and F1 above 0.93; Chrome/Firefox transfer well, Brave does not | Read for the cross-browser negative result and the imbalanced-data methodology; trackers were ≈0.26–0.5% of responses in their datasets | |
| | | Duumviri {[shuang2025_duumviri]}, NDSS 2025 | **Differential features** at the request-field level, plus a breakage detector | 97.44% agreement with filter-list labels on 53,217 requests; 95.39% on mixed responses; 74.19% lower bound on mixed fields; 22 new trackers | The most promising //partial// answer to the circularity: it still trains on EasyList/EasyPrivacy labels, but its features come from experimentally blocking the field and watching the page, so a disagreement is evidence about the page rather than about the URL string | |
| | | TGNN {[xiong2026_tgnn]}, TheWebConf 2026 | Graph attention network, **LLM-annotated** training data | F1 92.24% connected / 84.49% isolated requests; annotation F1 98.17%; pixel tracking on at least 16.74% of distinct domains | The only LLM-touching request classifier in this corpus; read it for the annotation pipeline | |
| |
| **PURL: Safe and Effective Sanitization of Link Decoration** {[shaoor2024purl]} | ===== Link Decoration and Tracking Parameters ===== |
| |
| | As third-party cookies disappear, identifiers move into the URL. **Link decoration** is the practice of appending information to a link — ''?fbclid=…'', ''?gclid=…'', ''?utm_source=…'' — so that the destination site, or a script on it, can recover an identifier without any cross-site storage. Classifying decorations is a different problem from classifying requests: the request may be entirely legitimate and only one query parameter privacy-relevant, so blocking is the wrong response and **sanitising** is the right one. |
| |
| ==== Classification of Cookie Notices and Their Interactive Elements ==== | **PURL** (**P**rivacy-preserving **URL**) {[shaoor2024purl]}, USENIX Security 2024, is the reference work. |
| |
| TODO | * **Method.** It builds a page-execution graph that also has //decoration nodes//, so a decoration can be linked to the storage value it came from and the script that put it there. Encoded values are matched by monitoring Base64, MD5, SHA-1 and SHA-256 encodings of storage values, which is how a hashed cookie in a URL is caught. A random forest is then trained on labels combining filter lists, Cookiepedia and manually curated tracking-parameter lists. |
| | * **Prevalence.** **73.02% of tested sites use link decoration for tracking**, with an average of **10.75 tracking decorations per site**. Those are the numbers to cite for "how common is this". |
| | * **Performance and cost.** 98.74% accuracy, 98.62% precision, 98.87% recall. Sanitising rather than blocking keeps breakage low: minor breakage on 5 of 100 sites and major breakage on 1 (a CSS load failure). |
| | * **The result that connects this page to [[Privacy:Fingerprinting|fingerprinting]].** Fingerprinting scripts initiated requests carrying **1,800 unique decorations, of which 200 were labelled as advertising or tracking** — decoration is one of the ways a fingerprint leaves the page. |
| | * **The experiment worth copying.** They ran crawls with and without entering deterministic identifiers (email addresses, names) and found **538 decorations present only in the identifier crawls**, 62 of them tracking. That differential design isolates identifier exfiltration from ordinary parameters far better than any static list, and it is cheap. |
| | |
| | **The lists, if you do not want to train a classifier.** Parameter-stripping rules are maintained by browser vendors rather than by the filter-list community, and they are not equally accessible. Checked 2026-08-12: |
| | |
| | ^ Source ^ Where the machine-readable list is ^ Notes ^ |
| | | **AdGuard URL Tracking filter** | ''https://filters.adtidy.org/windows/filters/17.txt'' (also per-platform) | **The best starting point.** Adblock syntax with ''$removeparam''; header carries ''Version: 2.0.13.86'', ''TimeUpdated: 2026-08-12T12:22:16+00:00'', ''Expires: 12 hours'' | |
| | | **uBlock Origin ''$removeparam''** | Not a separate list: an option used inside its subscribed lists, incl. AdGuard's above. Which lists ship is in [[https://github.com/uBlockOrigin/uAssets|uAssets]] | Cite the underlying list, not "uBlock" | |
| | | **Brave debouncing** | ''brave-lists/debounce.json'' in [[https://github.com/brave/adblock-lists|brave/adblock-lists]] | JSON, typed rules (''redirect'', ''base64,redirect'', ''regex-path''). Solves a related problem — bounce-through redirectors — not parameter stripping | |
| | | **Firefox query stripping** | Not in a repository — it is a **Remote Settings** collection, read at runtime by ''nsIUrlQueryStrippingListService''. Fetch it directly: ''https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/query-stripping/records'' returns the ''stripList'' and ''allowList'' as JSON, no auth. Local override prefs are ''privacy.query_stripping.strip_list'' / ''.allow_list'' | **Much shorter than the others**: 3 records, 23 stripped parameters and 1 allow-listed host on 2026-08-12 (''gclid'', ''fbclid'', ''msclkid'', ''mc_eid'', ''mkt_tok'' …). If you are comparing coverage, Firefox is not trying to do the same job as AdGuard's 2,492-rule filter | |
| | | **ClearURLs rules** | [[https://github.com/ClearURLs/Rules|ClearURLs/Rules]] | Rules data still updated (last push 2026-03-25); the extension itself has not been pushed since 2025-07-27 and a fork, Linkumori, positions itself as the maintained MV3 successor. **Verify the extension's status yourself before treating it as live** | |
| | |
| | <WRAP todo>Nobody has published a coverage-and-accuracy comparison of these parameter lists against each other, in the way Vallina et al. did for website categorisation services. PURL's own labels came from a union of them plus manual curation, which means the union has never been independently audited. This is a well-scoped, publishable measurement.</WRAP> |
| | |
| | ===== Cookie Notices and Their Interactive Elements ===== |
| | |
| | Finding the notice and labelling its buttons is a classification problem on **DOM elements**, and it is on this page because the methods are the same ones — a CSS-selector list, then a heuristic, then a small language model. What the notice //means// legally, and what to do about consent, is on [[Privacy:Consent|Granting Consent to Websites]]; the crawler-side mechanics of clicking are on [[Programming:Interaction|Interaction]]. |
| | |
| | **The pipeline everyone converges on has three stages, and each has a measured cost.** |
| | |
| | - **Find the notice.** Start with the **EasyList Cookie List** CSS selectors ([[Programming:Filter Lists#The lists|current rule counts here]] — it is overwhelmingly cosmetic, which is what you want for finding a banner) and add DOM/text heuristics: high ''z-index'', ''position: fixed'', a privacy-related keyword pool, a container that overlaps the viewport bottom or centre. |
| | - **Label the interactive elements.** Accept / reject / close / save / settings / other. Button text is short, multilingual and adversarially designed, which is why this is the stage that moved from keyword lists to learned models. |
| | - **Decide what to click, and verify it happened.** A click that silently fails is worse than no click, because the crawl continues and reports pre-consent behaviour as post-consent. The consent-interaction crawlers the field shares for this — BannerClick, Priv-Accept and the ''autoconsent'' integration built into [[Programming:Crawler:Tracker Radar Collector|Tracker Radar Collector]] — are compared on [[Programming:Crawler#Specialised Measurement Crawlers|the crawler page]]. |
| | |
| | ^ Study ^ Stage 1 method ^ Stage 2 method ^ Reported performance ^ |
| | | Matte et al. {[matte2020_cookie]}, IEEE S&P 2020 | Presence of the TCF ''\_\_cmp()'' API | — | Found a TCF banner on 1,426 of 22,949 sites (6.2%); a CMP API is a precise but narrow detector | |
| | | Rasaii et al. {[rasaii2023_thou]}, IMC 2023 | Word-and-currency heuristic for cookiewalls | — | **98.2% precision** on the detected set; cookiewalls on 280 of the ~45k sites crawled (0.6%) | |
| | | Khandelwal et al. {[khandelwal2023automated]}, USENIX Sec 2023 (CookieEnforcer) | Candidate-element extraction, then **BERT** | **T5-Large** predicting the click sequence | 986 of 2,000 domains, 2 false positives and 16 false negatives; **93.7% end-to-end** on 1,000 sites. At scale: notices on **52.7%** of 85,473 sites, 35.4% of them multi-view, and only **21.5%** offering a one-click opt-out | |
| | | Ogut et al. {[ogut2024_dissecting]}, USENIX Sec 2024 | XPath plus privacy-word pools, validated by hand | — | Notices on 37% of loaded sites; the paper to read on **language**, since button text is the classifier's input | |
| | | Bouhoula et al. {[bouhoula2024automated]}, USENIX Sec 2024 | EasyList Cookie List plus custom heuristics | **BERT** on 2353 hand-annotated interactive-element texts, six labels | **100.0% precision and 86.9% recall** on notice detection; the six-label element classifier reached **95.1% accuracy and F1 90.9%** in 5-fold cross-validation, with double annotation agreeing at **Cohen's κ = 91%** | |
| | | Demir et al. {[demir2024_bannertools]}, PETS 2024 | Compared existing banner-interaction extensions | — | Each extension interacts with **12 banners on average, 65%** of those shown (SD 21%, min 48%, max 95%) — the number to cite when you justify not using an off-the-shelf extension | |
| | | Tang et al. {[tang2025_navigating]}, USENIX Sec 2025 //(a compliance result, listed for its detector)// | Random forest on home pages, 1,000 hand-annotated | — | Global comparison; **96.18% (EU) to 97.72% (US)** of sites had at least one consent violation, and only 3.82% enforced preferences correctly | |
| | |
| | <WRAP important> |
| | **Two things a reviewer will ask, and the answers are in the table.** First, notice-detection //recall// is the weak number, not precision: Bouhoula et al. report 100.0% precision and 86.9% recall, so roughly one notice in seven is missed and every downstream rate is conditioned on the ones that were found. State your denominator as "of sites where we detected a notice", never "of sites". Second, an off-the-shelf banner-clicking extension interacts with about two thirds of banners {[demir2024_bannertools]}; if you use one, measure and report its success rate on your own sample. |
| | |
| | **Do not report a stateless crawl's consent numbers as if they were a user's experience.** Rasaii et al. {[rasaii2025_crumbs]} found that sites stop sending about **25% of "intractable" cookies only after the rejected page is reloaded**, and that sites with a CMP banner set **6.91 times** more of them than sites with a native banner. What you observe depends on whether you reloaded — see [[Programming:Stateful Stateless|stateful vs stateless crawling]]. |
| | </WRAP> |
| | |
| | Outside these seven venues, the WPES workshop at CCS is where a good deal of this work lands: Intumwayase et al. {[intumwayase2025_continents]} (WPES 2025) is a cross-continental study of cookie-notice enforcement and is not in any corpus figure on this page. |
| |
| ===== Use in Publications ===== | ===== Use in Publications ===== |
| |
| TODO | Everything in this section comes from a structured extraction over **5,859 full-text papers** from CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf and IEEE S&P, 2010–2026, one record per paper with a verbatim evidence quote per claim. The 2025 and 2026 venue-years are provisional — CCS and IMC 2026 have not been held, and IEEE S&P and WWW 2026 are incompletely selected — so any per-year row reaching them is under-represented by construction. Methodology and limitations are at the end of this section. |
| | |
| | ==== Two search handles, and they only partly overlap ==== |
| | |
| | There is no single field called "request classification", and if you search for one you will find half of it. The population for this section is built from two independent signals: |
| | |
| | ^ Membership signal ^ Papers ^ |
| | | **S1** — used or produced an advertising-or-tracking filter list | 197 | |
| | | **S2** — classified web requests for an advertising or tracking purpose | 164 | |
| | | both | 107 | |
| | | S1 only — a filter list used as an instrument in a paper about something else | 90 | |
| | | S2 only — classified requests without touching a public list | 57 | |
| | | **population = S1 ∪ S2** | **254** | |
| | |
| | **Only 42% of the population fires both signals.** That is the practical finding: the filter list has become a general-purpose third-party labelling instrument, reached for by papers on consent, passkeys, WebViews and satellite connectivity that would never describe themselves as tracker-detection work — while a large minority of request classification is done with bespoke heuristics that name no public list at all. |
| | |
| | The second signal needs narrowing, and the narrowing is itself informative. The raw enum value ''classification.target == "web-request"'' fires on **258** papers, and **94 of them are not about advertising or tracking at all** — infrastructure and CDN measurement, web-application security, spam and social-network abuse, bot detection, censorship, browser-extension security. The same over-catching happens on the list side: the regular expression that finds "a blocklist" also finds 35 papers using spam, malware, IP-reputation, content-category, censorship or certificate-revocation blocklists, which belong on [[design:website_classification|Website classification]] and [[design:ip_classification|IP classification]]. Every exclusion is named, counted and itemised on [[provenance:privacy:requests|the provenance page]] rather than dropped. |
| | |
| | ==== Where the papers are ==== |
| | |
| | ^ Venue ^ Corpus papers ^ Population papers ^ Share of venue ^ |
| | | PETS | 510 | 65 | 12.7% | |
| | | IMC | 638 | 44 | 6.9% | |
| | | TheWebConf | 843 | 41 | 4.9% | |
| | | USENIX Security | 1,410 | 33 | 2.3% | |
| | | CCS | 990 | 31 | 3.1% | |
| | | IEEE S&P | 767 | 27 | 3.5% | |
| | | NDSS | 701 | 13 | 1.9% | |
| | |
| | **PETS is more than six times more likely than NDSS to publish this work** (12.7% of its papers against 1.9%), and PETS plus IMC together carry 43% of it on 20% of the corpus. **Read that as venue //scope//, not as receptiveness**: PETS is a privacy-only venue, so of course this work is a larger share of it, and nothing here says anything about acceptance odds. As a reading-list ranking, though, it is the one to follow. |
| | |
| | ^ Period ^ Corpus papers ^ Population papers ^ Per 1,000 corpus papers ^ |
| | | 2010–2013 | 511 | 11 | 21.5 | |
| | | 2014–2017 | 769 | 33 | 42.9 | |
| | | 2018–2021 | 1,439 | 81 | 56.3 | |
| | | 2022–2024 | 1,955 | 79 | 40.4 | |
| | | 2025–2026 //(provisional)// | 1,185 | 50 | 42.2 | |
| | |
| | The peak is 2018–2021 — GDPR, the AdGraph lineage and the cookie-notice literature all landing at once — and the field has settled since at roughly 4% of these venues. |
| | |
| | ==== Which lists the field actually uses ==== |
| | |
| | Of the **197** papers that used or produced an advertising-or-tracking filter list. A paper naming several lists is counted under each, so the shares do not sum to 100%. Names were folded into families, because they are free text: the //Spellings folded// column is how many distinct strings the corpus uses for each. [[Programming:Filter Lists#Which lists|The filter-lists page]] computes the same table over a slightly wider population (198 papers, because it does not intersect with this page's request-classification task fold) and is the canonical version; the two differ by one or two papers per row, which is itself a useful illustration of how much a population definition moves a count. |
| | |
| | ^ Filter list ^ Papers ^ Share of 197 ^ Spellings folded ^ |
| | | EasyList | 110 | 55.8% | 32 | |
| | | EasyPrivacy | 71 | 36.0% | 26 | |
| | | Disconnect | 48 | 24.4% | 28 | |
| | | Ghostery / WhoTracks.me | 34 | 17.3% | 12 | |
| | | hosts-file lists (hpHosts, AdAway, MoaAB, Pi-hole, NoTrack, …) | 27 | 13.7% | 35 | |
| | | Adblock Plus (the lists shipped with it) | 26 | 13.2% | 12 | |
| | | uBlock Origin lists | 17 | 8.6% | 11 | |
| | | DuckDuckGo Tracker Radar | 15 | 7.6% | 9 | |
| | | **unnamed or merely counted** ("nine crowd-sourced filter lists") | 10 | 5.1% | 10 | |
| | | AdGuard | 8 | 4.1% | 13 | |
| | | EasyList annoyance / anti-adblock variants | 7 | 3.6% | 8 | |
| | | Privacy Badger //(a heuristic, not a list)// | 4 | 2.0% | 2 | |
| | | anti-adblock scripts and services | 3 | 1.5% | 4 | |
| | | cryptomining lists (NoCoin, CoinBlockerLists, MinerBlock) | 3 | 1.5% | 4 | |
| | | Acceptable Ads exception list | 1 | 0.5% | 1 | |
| | |
| | **Folding is not cosmetic here.** Counting exact strings undercounts EasyList by 18.2% (90 papers against 110), EasyPrivacy by 19.7%, Ghostery/WhoTracks.me by 11.8% — and **Disconnect by 45.8%** (26 against 48), because it appears as //Disconnect list//, //Disconnect.me//, //Disconnect blacklist//, //Disconnect Entity List//, //Disconnect Tracker Protection lists// and twenty-two other spellings. Any table of list adoption built on exact strings is wrong by tens of percent. |
| | |
| | Separately, the engines: tracker-radar-collector 10 papers (which is a [[Programming:Crawler:Tracker Radar Collector|crawler]], not a list — a distinction the raw names do not make), ''adblockparser'' 9, ''adblock-rust'' 7, uBlock Origin Core 2, ''abp-blocklist-parser'' 1, the Adblock Plus Android library 1. |
| | |
| | ==== "Mentioned" is not "used" ==== |
| | |
| | ^ Papers naming an advertising-or-tracking filter list ^ Papers ^ |
| | | in any field, with any ''usedOrMentioned'' value | 215 | |
| | | ''used'' or ''produced'' — the defensible "used it" claim | 197 | |
| | | difference, which a raw name search would score as adoption | 18 (8.4%) | |
| | |
| | By value, and a paper can appear in more than one row: 196 ''used'', 13 named only in an "other tools mentioned" field, 11 ''compared'' against as a baseline, 2 ''mentioned'', 2 ''produced''. The ''compared'' rows are the dangerous ones — a paper that beats EasyList is not a paper that adopted it. |
| | |
| | ==== How they classify ==== |
| | |
| | Of the **172** population papers carrying at least one ''web-request'' classification tuple they used or produced. ''classification.method'' agrees run-to-run on 58% of papers, so read this as a ranking, not as precise shares. |
| | |
| | ^ Method ^ Papers ^ Share of 172 ^ |
| | | ''blocklist'' | 98 | 57.0% | |
| | | ''heuristic-rules'' | 62 | 36.0% | |
| | | ''regex-or-signature'' | 18 | 10.5% | |
| | | ''third-party-service'' | 12 | 7.0% | |
| | | ''supervised-ml'' | 12 | 7.0% | |
| | | ''manual-labelling'' | 11 | 6.4% | |
| | | ''curated-database'' | 8 | 4.7% | |
| | | ''dynamic-analysis'' | 4 | 2.3% | |
| | | ''unsupervised-ml'' | 1 | 0.6% | |
| | | ''llm'' | 1 | 0.6% | |
| | |
| | ^ Period ^ Papers ^ ''blocklist'' ^ ''heuristic-rules'' ^ ''supervised-ml'' ^ ''llm'' ^ |
| | | 2010–2013 | 8 | 3 (37.5%) | 3 (37.5%) | 0 | 0 | |
| | | 2014–2017 | 21 | 11 (52.4%) | 8 (38.1%) | 0 | 0 | |
| | | 2018–2021 | 58 | 33 (56.9%) | 23 (39.7%) | 3 (5.2%) | 0 | |
| | | 2022–2024 | 53 | 38 (71.7%) | 14 (26.4%) | 6 (11.3%) | 0 | |
| | | 2025–2026 //(provisional)// | 32 | 13 (40.6%) | 14 (43.8%) | 3 (9.4%) | 1 (3.1%) | |
| | |
| | **Machine learning never displaced the filter list; it peaked at 11.3% of papers.** The visible drop in ''blocklist'' in the provisional last bucket sits on 32 papers and two incomplete venue-years, so do not read a trend into it. The one thing the last row does establish is that LLM classification of requests has exactly one instance in these venues, in 2026. |
| | |
| | ==== Ground truth, and the circularity ==== |
| | |
| | Of the **14** population papers with a learned ''web-request'' classification tuple (''supervised-ml'', ''unsupervised-ml'' or ''llm''): |
| | |
| | ^ Ground-truth source ^ Papers ^ Share of 14 ^ |
| | | **a filter list** | 8 | 57.1% | |
| | | manual or human labelling | 4 | 28.6% | |
| | | another stated source | 2 | 14.3% | |
| | | none stated | 0 | 0.0% | |
| | |
| | The eight are NoMoAds, AdGraph, Khaleesi, WebGraph, WTAGRAPH, AdFlush, Beyond the Request and Duumviri — that is, **every system this page recommends as a baseline, without exception**. Duumviri is the closest thing to a break in the pattern and it is not one: it takes its tracking-detector labels from EasyList and EasyPrivacy like the rest (12,936 tracker and 14,785 non-tracker cases from the Alexa top 5K), and what is independent is its //features// and its separately-trained breakage detector, whose positive samples are reconstructed from exception rules and user reports rather than from tracking labels. **Nobody in this corpus has trained a request classifier without a filter list somewhere in the loop.** |
| | |
| | Validation, over the same 172 papers as above: |
| | |
| | ^ ''classification.validation'' ^ Papers ^ Share of 172 ^ |
| | | manual validation | 61 | 35.5% | |
| | | **none reported** | 60 | 34.9% | |
| | | not applicable //(sentinel)// | 58 | 33.7% | |
| | | comparison to another method | 10 | 5.8% | |
| | | cross-validation | 7 | 4.1% | |
| | | held-out test set | 5 | 2.9% | |
| | |
| | **One paper in three reports no validation of its request classification at all.** The ''not-applicable'' row is mostly papers that applied a list as-is and reasonably consider the list itself the definition — **45 of those 58 papers** carry that ''not-applicable'' verdict on a ''blocklist'' tuple — which is exactly the assumption Calzavara et al. {[calzavara2026_syntactic]} measured at 16%–19% false positives. Manual validation of a sample is an afternoon's work and it is the single cheapest thing you can add. |
| | |
| | ==== Almost nobody says which version of the list ==== |
| | |
| | Of the **177** papers naming a filter list as a tool they used or produced, **52 (29.4%)** attach any version or date to it. Read that as an order of magnitude in both directions: the extraction fills the version field only when the paper puts a version next to the name, so a paper that dates its lists in a crawl paragraph may not be credited — and several of the 52 give an //extension// version (''Ghostery 5.4.1'', ''Adblock Plus 2.6.7'') rather than a list version, which does not identify the rules. Precise datings do exist and are the model to copy: //EasyList and EasyPrivacy, downloaded January 29, 2019//; //EasyList (EL), March 13, 2020//; //whotracks.me, 2019-09-25//. |
| | |
| | Given that EasyList publishes both a ''Version:'' and the exact ''Commit:'' in its own header, and that it changed twice within thirteen minutes on the day this page was written, a 70% silence rate is the largest single reproducibility gap on this page. |
| | |
| | ==== Crawl configuration of these papers ==== |
| | |
| | 201 of the 254 ran an automated web crawl; 197 have a recorded crawl configuration. Of those, **52.3% state a consent action**, 46.2% state whether the crawl was stateful, 23.4% state headless or headful, and 95.4% state an interaction depth. Consent action matters more here than on most pages: a crawl that accepted everything and a crawl that never touched the banner are measuring different webs, and nearly half the papers do not say which they did. See [[Programming:Crawler#Configuration reporting, and whether the tool predicts it|the crawler page]] for the corpus-wide comparison. |
| | |
| | ==== Methodology and limitations of these figures ==== |
| | |
| | * **How they were produced.** One structured record per paper was extracted from full text, each tuple carrying a verbatim evidence quote and its section. The script that produces every number in this section, with its denominators, is ''report_requests.mjs''; the folding rules are in ''req_fold.mjs''; ''verify_requests_figures.mjs'' re-checks every per-paper figure on this page against the paper's own text. Every query, the scripts' unedited output and the full residue are on [[provenance:privacy:requests|the provenance page for this one]]; corpus-level caveats are on [[literature:corpus]]. |
| | * **The population is a judgement, not an enum.** No field in the extraction means "classifies requests as tracking". S1 and S2 above are proxies, both are folded free text or a hand-written task rule, and both are stated in full on the provenance page so you can disagree with them. |
| | * **A paper counts once**, never once per tuple, and shares do not sum to 100% because the fields are multi-valued. |
| | * **Sentinels are counted as what they are.** ''not-stated'', ''none-reported'' and ''not-applicable'' are never folded into a stated value; where they are the largest row, that is the finding. |
| | * **Free-text names were folded before counting.** The residue is printed rather than dropped: 34 distinct strings across 35 tuples matched no list family, and almost all are generic off-topic phrases (''12 IP reputation blacklists'', ''combined public blacklists'', ''eCrimeX blacklist''). The full list is on the provenance page. |
| | * **Every per-paper figure on this page was checked against the paper's own full text**, not against the extraction's summary of it: of 143 literal figures, 141 were found verbatim in ''paper.cols.txt'' and 2 as a listed spelling variant (Matte et al. write ''1 426'' and ''22 949'' with a thin space). That pass caught a real error: the extraction's summary of Rasaii et al. {[rasaii2023_thou]} gives a denominator of "45,222 websites", and **that number is nowhere in the paper**, which says "we crawled 45k websites and found cookiewalls on 280 of them". The page says ~45k. Snyder et al. is a SIGMETRICS paper outside these seven venues, so its 90.16% was verified against the paper directly rather than through the corpus. |
| | * **Venue coverage.** Seven venues only. EuroS&P, ACSAC, RAID, AsiaCCS, WPES, CHI and SOUPS are absent, and several works this page relies on were published outside the seven — Snyder et al. at SIGMETRICS, Intumwayase et al. at WPES, and the Vekaria et al. SoK on arXiv. Any count here is a lower bound on a system's standing. |
| | * **Stability.** ''classification.method'' agrees with an independent extraction run on 58% of papers and free-text names on about 20% of exact strings; enum fields such as ''classification.validation'' are considerably more stable. That is why methods are given as rankings and validation as percentages. |
| | |
| | ===== What to Report ===== |
| | |
| | - **The list, its version and its commit**, and the archived ''.txt'' — not "EasyList". 70% of papers give no version at all and 98% give nothing that identifies the rules. [[Programming:Filter Lists#Recording Which List You Used|How, and a script that does it]]. |
| | - **The engine and its version**, separately from the list, because two parsers of the same list do not match the same rules and the older ones silently ignore options they do not know. [[Programming:Filter Lists#Post-processing beats blocking at crawl time|Which engines are maintained]]. |
| | - **Which rule kinds you evaluated.** Network only, or cosmetic too? Nearly a third of EasyList is cosmetic and answers a different question. |
| | - **The unit, and how you decided "party".** Domain, eTLD+1, URL, chain or parameter — and whether party is by public suffix list (name which one) or by **entity map** (name which one). The two give different third-party rates for the same crawl. |
| | - **What you did with mixed resources**, given that 48% of hostnames are mixed {[amjad2021_trackersift]}. |
| | - **Validation on your own sample.** Hand-label a few hundred requests and report precision against the list. One paper in three reports nothing here. |
| | - **If you trained a classifier: what supplied the labels**, and what you think the label noise is. "Filter lists" is an answer with a known error rate now {[calzavara2026_syntactic]} — quote it. |
| | - **Your consent action and statefulness**, because tracking requests are conditional on both. |
| | - **If you used a banner-clicking tool: its success rate on your sample**, not its authors' {[demir2024_bannertools]}. |
| | |
| | ===== Open Questions ===== |
| | |
| | <WRAP todo> |
| | * **No independent audit of the tracking-parameter lists exists** (see [[#Link Decoration and Tracking Parameters]]). PURL's ground truth is their union. |
| | * **Nobody has repeated the filter-list-versus-behaviour comparison on a modern crawl at scale.** Calzavara et al. {[calzavara2026_syntactic]} did it for one taint-tracking browser on 7,614 sites; Fouad et al. {[fouad2020_missed]} did it behaviourally in 2020. The 16%–19% false-positive figure is currently a single data point that a lot of this page leans on. |
| | * **The Brave transfer failure in Beyond the Request {[rieder2025_beyond]} is unexplained.** Whether it is Brave's own blocking changing the observable distribution, or something about its request handling, is a small and answerable question. |
| | * **Python has no maintained filter-list engine.** Someone should either revive ''python-adblock'' against ''adblock'' 0.13.x or state loudly that Python pipelines must shell out. |
| | * **Nothing in this corpus escapes the filter list.** All 8 learned request classifiers train on filter-list labels, Duumviri included. The two directions that come closest — Duumviri's differential features and breakage detector {[shuang2025_duumviri]}, and taint tracking as an independent detector {[calzavara2026_syntactic]} — have each been done once. **A request classifier whose labels come from something other than a list is an open problem, and it is the one this page would most like solved.** |
| | * **What Manifest V3 did to extension-based measurement.** Lukić and Papadopoulos {[lukic2026_mv3]} found no significant loss of blocking effectiveness under ''declarativeNetRequest'', but the 30,000-rule static cap is well under EasyList's network-rule count ([[Programming:Filter Lists#If your instrument is a browser extension: Manifest V3 caps the rules|current figure here]]) and nobody has published which rules the shipped MV3 blockers drop, or what that omits from a measurement. |
| | * **Venue coverage is itself an open problem for this topic.** AdVersa {[lim2026_adversa]} at TheWebConf 2026 and Intumwayase et al. {[intumwayase2025_continents]} at WPES 2025 are both squarely in scope and both invisible to the figures above. A reading list built only from the seven venues in this corpus will be incomplete for exactly the most recent work. |
| | </WRAP> |
| | |
| | ===== Related Pages ===== |
| | |
| | * [[Programming:Crawler|Comparison of crawling libraries]] — what records the initiator chain, the call stack and the response headers these methods need. |
| | * [[Programming:Crawler:Tracker Radar Collector|Tracker Radar Collector]] — the lowest-effort crawler for this task, and where the Tracker Radar data comes from. |
| | * [[Programming:Crawler:PageGraph|Brave PageGraph]] — AdGraph's production successor, and the practical way to get a page-execution graph. |
| | * [[Programming:Crawler:webXray|webXray and domain-to-company ownership]] — once a request is flagged, this is how to answer //whose// it is, and why webXray, Tracker Radar and Disconnect give three different answers. |
| | * [[Privacy:JavaScript|Analysing and classifying JavaScript]] — the script-level and function-level end of the granularity ladder. |
| | * [[Privacy:Cookies|Cookies]] and [[Privacy:Fingerprinting|Fingerprinting]] — the other two things a "tracking" label is often about. |
| | * [[Privacy:Cookie syncing|Measuring cookie and ID syncing]] — the exchange that makes those identifiers joinable across parties, and the reason the link-decoration section above exists. |
| | * [[Privacy:Consent|Granting consent to websites]] — what the cookie notice means, once you have found it. |
| | * [[Design:Website Classification|Website classification]] — and the measured reason **not** to use a categorisation service to find trackers. |
| | * [[Programming:Stateful Stateless|Stateful vs stateless crawling]] and [[Programming:Interaction|Interaction]]. |
| | * [[provenance:privacy:requests|Provenance of this page's figures]]. |
| |
| ====== References ====== | ====== References ====== |
| |
| ~~DISCUSSION~~ | ~~DISCUSSION~~ |
| | |