User Tools

Site Tools


security:web_vulnerabilities

This is an old revision of the document!


Web vulnerabilities

You are about to look for XSS, CSRF, clickjacking or a same-origin bypass on live sites. This page is the methods and denominators for that measurement, from the seven-venue corpus behind this site. It is not an attack tutorial. Ethics of scanning live sites is Ethics (Hantke et al. [1Hantke, Florian; Roth, Sebastian; Mrowczynski, Rafael; Utz, Christine; Stock, Ben (2024): "Where Are the Red Lines? Towards Ethical Server-Side Scans in Security and Privacy Research", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]); telling the operator is Notifying websites. Script-level analysis without an exploitability claim is JavaScript. CSP, HSTS and the other headers a crawl can see are Headers.

The corpus is 5,859 extracted papers from CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf and IEEE S&P, 2010–2026. 1,120 ran a crawl. 2025–2026 are provisional. Queries, the role map and the unedited report are on web_vulnerabilities. Corpus-wide caveats: Corpus.

880 papers classify a vulnerability. That is not this page's population.

  • 880 papers used or produced a classification.target == vulnerability tuple (15.0% of 5,859).
  • 209 of those 880 are on the web platform (23.8%).
  • 99 are web and crawled (11.3% of 880; 8.8% of 1,120 crawled papers).
  • 433 of 880 (49.2%) are offline (program analysis of software) — a paper-level platform tag, and a paper can have several platforms.
  • Of the 99, a hand map splits 30 wild / 27 lab / 8 cve / 34 offtopic. The 30 are the papers that crawled live (or archived) sites to measure a web-application or client-side vulnerability class. 30 of 1,120 crawled papers (2.7%). Treating 880, 209 or 99 as “the field measured XSS in the wild” is the mistake this page exists to stop.

The 99 is a paper-level conjunction: it does not by itself mean the crawl is how the vulnerability was found. Nuclei / Nikto / w3af / OpenVAS together hit 24 papers in full text — too thin for a scanner-tool page; they are a residue here.

What to read first

Paper Why
Steffens et al., NDSS 2019, Don't Trust The Locals [2Steffens, Marius; Rossow, Christian; Johns, Martin; Stock, Ben (2019): "Don't Trust The Locals: Investigating the Prevalence of Persistent Client-Side Cross-Site Scripting in the Wild", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] Persistent client-side XSS in the Alexa Top 5,000. More than 8% of those domains had unfiltered flows from cookies or Web Storage to a dangerous sink; 418 of 1,324 domains that used stored data in a sink were exploitable; 468 of 5,000 were susceptible to reflected client-side XSS. Start here.
Lekies, Stock and Johns, CCS 2013, 25 Million Flows Later [3Lekies, Sebastian; Stock, Ben; Johns, Martin (2013): "25 Million Flows Later: Large-scale Detection of DOM-based XSS", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] DOM XSS on the Alexa top 5,000: 6,167 unique vulnerabilities on 480 domains (9.6%). 69,987 of 181,238 generated payloads executed. The two numbers — vulns vs domains — are the unit trap.
Bau et al., IEEE S&P 2010, State of the Art: Automated Black-Box Web Application Vulnerability Testing [4Bau, Jason; Bursztein, Elie; Gupta, Divij; Mitchell, John C. (2010): "State of the Art: Automated Black-Box Web Application Vulnerability Testing", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] Dated as current practice (2010 scanners on known apps). The finding that aged well: reflected XSS detection over 60%; stored XSS 15%; second-order SQL injection detected by no scanner.
Son and Shmatikov, NDSS 2013, The Postman Always Rings Twice [5Son, Sooel; Shmatikov, Vitaly (2013): "The Postman Always Rings Twice: Attacking and Defending postMessage in HTML5 Websites", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] postMessage origin checks in the wild: 1,712 hosts with missing or incorrect checks; 13 receivers compromising 84 hosts. SOP as a crawl, not a textbook.
Chehade, Hantke and Stock, IEEE S&P 2025, 403 Forbidden? [6Chehade, Saiid El Hajj; Hantke, Florian; Stock, Ben (2025): "403 Forbidden? Ethically Evaluating Broken Access Control in the Wild", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] Broken access control in the wild, with confirmation: 19 vulnerabilities across 7 of 100 sites, from 30 improper endpoints on 15 sites. The methods section is the ethics section.

The 99, then the 30

Membership is mechanical: a used or produced vulnerability classification, platforms includes web, and the paper is in the crawled population (crawlConfig present or studyTypes includes automated-web-crawl). That is 99 papers. scripts/vuln_fold.mjs then assigns one role per paper; the report exits 1 if the map and the conjunction disagree.

Role Papers of 99 Share of 99 Share of 1,120 crawled Meaning
wild 30 30.3% 2.7% Crawled live or archived sites to measure a web-application or client-side vulnerability class.
lab 27 27.3% 2.4% Evaluated a scanner, fuzzer or analyser on known applications or a testbed.
cve 8 8.1% 0.7% Mapped CVE/NVD/Snyk/Wooyun labels onto libraries, patches or crawled resources.
offtopic 34 34.3% 3.0% Not that measurement (malware, TLS, firmware, payments-as-product, …).

The page population for “in the wild” figures is the 30. Lab papers are how the field tests detectors; they are not a prevalence of live sites. CVE papers answer “is this library version known-bad”, which is a different question from “is this origin exploitable today”.

A kind fold over title, slug and the vulnerability tuples (multi-label) among the 99:

Kind Papers of 99 of which wild of which lab
xss 25 14 11
csrf 7 7 0
clickjacking 1 0 0
sop 4 4 0
sqli 4 0 4
client-other (prototype pollution, DOM clobbering, request hijacking, open redirect, cache deception) 7 7 0
server-other (SSRF, IDOR, SSTI, ReDoS, command injection) 6 1 5

62 of 99 matched no family — residue, printed in the report. Clickjacking as a primary study is essentially absent from this schema slice. A full-text clickjack probe over the 857 web-and-crawled papers hits 39 (upper bound: mentions, related work, X-Frame-Options asides). Do not publish 39 as the clickjacking literature.

One of the 99 is a poster (CCS 2024 login-interface ZAP scan). The corpus has 138 posters; they compress methods out and bias silence figures up. See Corpus.

USENIX contributes 10 of the 30 wild papers; TheWebConf and IMC contribute 0. 2022–2024 holds 12 of 30 (40.0%) of the wild role; 2025–2026* holds 6 of 30 (20.0%) and is incomplete by construction.

What a crawl can actually find

Three XSS stories share a name and almost no method. Date them.

Reflected (server). The payload is in the request and comes back in the response. Bau et al. [4Bau, Jason; Bursztein, Elie; Gupta, Divij; Mitchell, John C. (2010): "State of the Art: Automated Black-Box Web Application Vulnerability Testing", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] already saw scanners do this relatively well (over 60% detection on their known-vuln set) and fail at stored XSS (15%) and at second-order SQL injection (none). That comparison is 2010, on historical applications plus a custom testbed — a lab result. It is still the right intuition for a landing-page black-box scan: you will over-sample reflected XSS and under-sample anything that needs stored state.

Stored (server). The payload is written and replayed later. Spider-Scents [7Olsson, Eric; Eriksson, Benjamin; Doupé, Adam; Sabelfeld, Andrei (2024): "Spider-Scents: Grey-box Database-aware Web Scanning for Stored XSS", in: Proceedings of the USENIX Security Symposium. (Link)] and Black Widow [8Eriksson, Benjamin; Pellegrino, Giancarlo; Sabelfeld, Andrei (2021): "Black Widow: Blackbox Data-driven Web Scanning", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] are detector papers on known apps, not a live-web prevalence. Counting “the scanner alerted” as “the site is vulnerable” is the next section.

DOM / client-side. The source and the sink are both in the page's JavaScript. Lekies et al. [3Lekies, Sebastian; Stock, Ben; Johns, Martin (2013): "25 Million Flows Later: Large-scale Detection of DOM-based XSS", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] taint-tracked the Alexa top 5,000 and validated by executing a payload69,987 of 181,238 generated payloads ran. Steffens et al. [2Steffens, Marius; Rossow, Christian; Johns, Martin; Stock, Ben (2019): "Don't Trust The Locals: Investigating the Prevalence of Persistent Client-Side Cross-Site Scripting in the Wild", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] added persistent client-side XSS: the source is document.cookie or Web Storage, so a payload that stuck yesterday fires on a later visit. Of domains that used stored data in a sink, 21% were vulnerable; of the 418 exploitable domains, a network attacker could use 293 and a web attacker 65. Stock et al. [9Stock, Ben; Johns, Martin; Steffens, Marius; Backes, Michael (2017): "How the Web Tangled Itself: Uncovering the History of Client-Side Web (In) Security", in: 26th USENIX Security Symposium (USENIX Security 17), pp. 971-987. USENIX Association, Vancouver, BC. (Link)] put an 8% client-side XSS rate on 2016 sites in a Wayback crawl. That taint-and-confirm pipeline is what the 2024–2026 specialised browsers still do — see Foxhound and PanoptiChrome.

Related client-side classes that this corpus did measure in the wild, and that a “we crawled for XSS” paper will miss if it only looks at innerHTML:

  • postMessage / SOP. Son and Shmatikov [5Son, Sooel; Shmatikov, Vitaly (2013): "The Postman Always Rings Twice: Attacking and Defending postMessage in HTML5 Websites", in: Proceedings of the Network and Distributed System Security Symposium. (Link)]: 22% of visited hosts used postMessage; missing or incorrect origin checks on 1,712 hosts; 13 receivers compromising 84 hosts.
  • Prototype pollution. Kang, Li and Cao [10Kang, Zifeng; Li, Song; Cao, Yinzhi (2022): "Probe the Proto: Measuring Client-Side Prototype Pollution Vulnerabilities of One Million Real-world Websites", in: Proceedings of the Network and Distributed System Security Symposium. (DOI)]: 2,738 of one million sites, 2,917 exploitable vulns; 48 led to XSS, 736 to cookie manipulation, 830 to URL manipulation.
  • DOM clobbering. Khodayari and Pellegrino [11Khodayari, Soheil; Pellegrino, Giancarlo (2023): "It's (DOM) Clobbering Time: Attack Techniques, Prevalence, and Defenses", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]: 9.8% of 5,000 sites (491); 44 with a proof-of-concept exploit.
  • Request hijacking. Khodayari, Barber and Pellegrino [12Khodayari, Soheil; Barber, Thomas; Pellegrino, Giancarlo (2024): "The Great Request Robbery: An Empirical Study of Client-side Request Hijacking Vulnerabilities on the Web", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]: 9.6% of the top 10K sites; 67 PoCs across 49 sites.
  • Blind XSS. Kirchner et al. [13Kirchner, Robin; Möller, Jonas; Musch, Marius; Klein, David; Rieck, Konrad; Johns, Martin (2024): "Dancer in the Dark: Synthesizing and Evaluating Polyglots for Blind Cross-Site Scripting", in: Proceedings of the USENIX Security Symposium. (Link)]: 20 vulnerabilities on 18 websites (headers triggered 10, URLs 9, forms 1). A landing-page GET will not see these.
  • CSRF / SameSite. Khodayari and Pellegrino [14Khodayari, Soheil; Pellegrino, Giancarlo (2022): "The State of the SameSite: Studying the Usage, Effectiveness, and Adequacy of SameSite Cookies", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]: 7 of 264 sampled GET requests forgeable (four websites); 9 of 602 POST-to-GET (six websites). SameSite is not “CSRF is solved”.
  • Cache deception. Mirheidari et al. [15Mirheidari, Seyed Ali; Arshad, Sajjad; Onarlioglu, Kaan; Crispo, Bruno; Kirda, Engin; Robertson, William (2020): "Cached and Confused: Web Cache Deception in the Wild", in: Proceedings of the USENIX Security Symposium. (Link)] and the 2022 escalation [16Mirheidari, Seyed Ali; Golinelli, Matteo; Onarlioglu, Kaan; Kirda, Engin; Crispo, Bruno (2022): "Web Cache Deception Escalates!", in: Proceedings of the USENIX Security Symposium. (Link)].
  • Broken access control. Chehade et al. [6Chehade, Saiid El Hajj; Hantke, Florian; Stock, Ben (2025): "403 Forbidden? Ethically Evaluating Broken Access Control in the Wild", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] as above. OWASP Top 10:2025 still puts Broken Access Control at A01; XSS sits inside A05 Injection (CWE-79), not as its own Top-10 letter.1)

Clickjacking is named in the namespace brief and almost unmeasured in this slice: 0 wild papers in the kind fold, 1 paper of 99, 39 full-text hits among 857 web-and-crawled papers as an upper bound. Do not pad the page with an MDN explanation of X-Frame-Options. If you are measuring clickjacking, you are not following a well-trodden corpus method — say so.

Why a landing-page crawl undercounts

Among the 30 wild papers:

crawlConfig.interactionDepth Papers of 30
deep-crawl 10 (33.3%)
landing-plus-subpages 9 (30.0%)
single-target-page 5 (16.7%)
landing-page-only 2 (6.7%)
not-stated 2 (6.7%)
no crawlConfig 2 (6.7%)

7 of 30 (23.3%) are landing-page-only or single-target-page. 10 of 30 state a subpagesPerSite number. The schema label is one quote for the whole crawlConfig object — see Interaction for the discriminant and for the field-wide figure (155 of 417 (37.2%) on the site-depth axis stayed on the landing page, among 857 web crawls). That 37.2% is quoted from that page, not re-derived here.

What a front page misses, concretely:

  • Stored XSS needs a write then a later read, often behind a form or a logged-in view.
  • Blind XSS fires in an admin panel the crawler never sees [13Kirchner, Robin; Möller, Jonas; Musch, Marius; Klein, David; Rieck, Konrad; Johns, Martin (2024): "Dancer in the Dark: Synthesizing and Evaluating Polyglots for Blind Cross-Site Scripting", in: Proceedings of the USENIX Security Symposium. (Link)].
  • DOM XSS after interaction. Sabino et al. [17Sabino, Nuno; Cassel, Darion; Abreu, Rui; Adão, Pedro; Bauer, Lujo; Jia, Limin (2026): "DOM-XSS Detection via Webpage Interaction Fuzzing and URL Component Synthesis", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] (NDSS 2026, provisional year) fuzz in-page interaction and URL-component synthesis because a load-and-taint pass misses flows that only exist after a click. Foxhound's own default sources do not include every URL fragment; the 2026 DOM-XSS paper treats that as a finding, not a footnote.
  • CSRF needs a state-changing request the landing GET does not issue [14Khodayari, Soheil; Pellegrino, Giancarlo (2022): "The State of the SameSite: Studying the Usage, Effectiveness, and Adequacy of SameSite Cookies", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)].
  • Broken access control needs two accounts or a guessed URL [6Chehade, Saiid El Hajj; Hantke, Florian; Stock, Ben (2025): "403 Forbidden? Ethically Evaluating Broken Access Control in the Wild", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)].

A methods section that says “we crawled the Tranco top N landing pages for XSS” is answering a different question from Steffens or Lekies. Write the question.

How papers count "vulnerable sites"

Lekies et al. [3Lekies, Sebastian; Stock, Ben; Johns, Martin (2013): "25 Million Flows Later: Large-scale Detection of DOM-based XSS", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] report 6,167 unique vulnerabilities and 480 domains. Publishing only the first makes the web look an order of magnitude worse; publishing only the second hides that some origins are riddled. Kang et al. [10Kang, Zifeng; Li, Song; Cao, Yinzhi (2022): "Probe the Proto: Measuring Client-Side Prototype Pollution Vulnerabilities of One Million Real-world Websites", in: Proceedings of the Network and Distributed System Security Symposium. (DOI)] similarly: 2,917 vulns on 2,738 domains. Khodayari et al. [12Khodayari, Soheil; Barber, Thomas; Pellegrino, Giancarlo (2024): "The Great Request Robbery: An Empirical Study of Client-side Request Hijacking Vulnerabilities on the Web", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]: 202,834 verified flows, 17,805 pages, 961 sites. Chehade et al. [6Chehade, Saiid El Hajj; Hantke, Florian; Stock, Ben (2025): "403 Forbidden? Ethically Evaluating Broken Access Control in the Wild", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]: 30 improper endpoints on 15 sites, then 19 confirmed vulns on 7 sites. Those are four different units.

Name the unit in the sentence: origin, registrable domain, URL, sink, flow, or confirmed exploit. The script below refuses to let a CSV of scanner rows collapse them.

count_vuln_sites.py
#!/usr/bin/env python3
"""Count scanner findings the way a methods section has to.
 
A taint flow, a ZAP alert, and a confirmed exploit are three different units.
This script refuses to let them collapse. Input is CSV with a header:
 
    url,sink,confirmed
 
``confirmed`` is required and must be one of true/false/yes/no/1/0 (case
insensitive). Missing column → crash. Counting unique URLs as "vulnerable
sites" is the other failure mode this prints: Lekies et al. (CCS 2013) found
6,167 unique vulnerabilities on 480 domains. Those are not the same number.
 
Usage:
    uv run python pages/count_vuln_sites.py findings.csv
    uv run python pages/count_vuln_sites.py --demo
    uv run python pages/count_vuln_sites.py --selftest
"""
 
from __future__ import annotations
 
import csv
import io
import sys
from collections import Counter
from urllib.parse import urlparse
 
TRUE = {"true", "yes", "1"}
FALSE = {"false", "no", "0"}
 
DEMO_CSV = """url,sink,confirmed
https://a.example/page?q=1,innerHTML,true
https://a.example/page?q=2,innerHTML,true
https://a.example/other,eval,false
https://b.example/,document.write,true
https://c.example/x,innerHTML,false
"""
 
 
def host_of(url: str) -> str:
    # urlparse.hostname is None for a URL with no host; .lower() then raises.
    return urlparse(url).hostname.lower()
 
 
def parse_confirmed(raw: str, line_no: int) -> bool:
    token = raw.strip().lower()
    if token in TRUE:
        return True
    if token in FALSE:
        return False
    raise ValueError(
        f"line {line_no}: confirmed={raw!r} is not one of true/false/yes/no/1/0"
    )
 
 
def analyse(text: str) -> dict:
    reader = csv.DictReader(io.StringIO(text))
    header = reader.fieldnames
    for col in ("url", "sink", "confirmed"):
        if col not in header:
            raise KeyError(f"required column {col!r} missing; got {header}")
    n_rows = 0
    urls: set[str] = set()
    hosts: set[str] = set()
    confirmed_hosts: set[str] = set()
    confirmed_urls: set[str] = set()
    sinks: Counter[str] = Counter()
    confirmed_n = 0
    for i, row in enumerate(reader, start=2):
        n_rows += 1
        url = row["url"]
        sink = row["sink"]
        confirmed = parse_confirmed(row["confirmed"], i)
        if url == "":
            raise ValueError(f"line {i}: empty url")
        if sink == "":
            raise ValueError(f"line {i}: empty sink")
        urls.add(url)
        host = host_of(url)
        hosts.add(host)
        sinks[sink] += 1
        if confirmed:
            confirmed_n += 1
            confirmed_urls.add(url)
            confirmed_hosts.add(host)
    return {
        "rows": n_rows,
        "unique_urls": len(urls),
        "unique_hosts": len(hosts),
        "confirmed_rows": confirmed_n,
        "confirmed_urls": len(confirmed_urls),
        "confirmed_hosts": len(confirmed_hosts),
        "unconfirmed_rows": n_rows - confirmed_n,
        "sinks": sinks,
    }
 
 
def render(stats: dict) -> str:
    lines = [
        f"findings (rows)                         {stats['rows']}",
        f"unique URLs                             {stats['unique_urls']}",
        f"unique hosts                            {stats['unique_hosts']}",
        f"confirmed rows                          {stats['confirmed_rows']}",
        f"confirmed unique URLs                   {stats['confirmed_urls']}",
        f"confirmed unique hosts                  {stats['confirmed_hosts']}",
        f"unconfirmed rows                        {stats['unconfirmed_rows']}",
        "sinks:",
    ]
    for sink, n in stats["sinks"].most_common():
        lines.append(f"  {sink}\t{n}")
    lines.append(
        "Do not publish unique URLs as sites, or unconfirmed rows as vulnerabilities."
    )
    return "\n".join(lines)
 
 
def selftest() -> None:
    stats = analyse(DEMO_CSV)
    expect = {
        "rows": 5,
        "unique_urls": 5,
        "unique_hosts": 3,
        "confirmed_rows": 3,
        "confirmed_urls": 3,
        "confirmed_hosts": 2,
        "unconfirmed_rows": 2,
    }
    for k, v in expect.items():
        if stats[k] != v:
            raise AssertionError(f"selftest {k}: got {stats[k]!r} want {v!r}")
    if dict(stats["sinks"]) != {"innerHTML": 3, "eval": 1, "document.write": 1}:
        raise AssertionError(f"selftest sinks: {dict(stats['sinks'])}")
    try:
        analyse("url,sink\nhttps://a.example/,innerHTML\n")
    except KeyError as e:
        if "confirmed" not in str(e):
            raise
    else:
        raise AssertionError("missing confirmed column did not raise")
    try:
        analyse("url,sink,confirmed\nhttps://a.example/,innerHTML,maybe\n")
    except ValueError as e:
        if "confirmed" not in str(e):
            raise
    else:
        raise AssertionError("bad confirmed token did not raise")
    print("selftest OK")
 
 
def main() -> None:
    if len(sys.argv) != 2:
        raise SystemExit(
            "usage: count_vuln_sites.py <findings.csv> | --demo | --selftest"
        )
    arg = sys.argv[1]
    if arg == "--selftest":
        selftest()
        return
    if arg == "--demo":
        print(render(analyse(DEMO_CSV)))
        return
    text = open(arg, encoding="utf-8").read()
    print(render(analyse(text)))
 
 
if __name__ == "__main__":
    main()

Real --demo output (byte-identical on 2026-08-27):

findings (rows)                         5
unique URLs                             5
unique hosts                            3
confirmed rows                          3
confirmed unique URLs                   3
confirmed unique hosts                  2
unconfirmed rows                        2
sinks:
  innerHTML	3
  eval	1
  document.write	1
Do not publish unique URLs as sites, or unconfirmed rows as vulnerabilities.

Five rows, three hosts, two confirmed hosts. A paper that published “5 vulnerable sites” from that file would be wrong twice.

A scanner finding is not a confirmed exploit

Bau et al. [4Bau, Jason; Bursztein, Elie; Gupta, Divij; Mitchell, John C. (2010): "State of the Art: Automated Black-Box Web Application Vulnerability Testing", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] is the dated lab baseline: scanners as a group found reflected XSS and missed stored XSS and second-order SQLi. Eriksson, Pellegrino and Sabelfeld [8Eriksson, Benjamin; Pellegrino, Giancarlo; Sabelfeld, Andrei (2021): "Black Widow: Blackbox Data-driven Web Scanning", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] (Black Widow) report 25 unique XSS injections including 6 previously unknown, and no false positives on the tested applications — after manual analysis of whether the injection executes. Lekies et al. [3Lekies, Sebastian; Stock, Ben; Johns, Martin (2013): "25 Million Flows Later: Large-scale Detection of DOM-based XSS", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] generated payloads and counted only those that ran. Steffens et al. [2Steffens, Marius; Rossow, Christian; Johns, Martin; Stock, Ben (2019): "Don't Trust The Locals: Investigating the Prevalence of Persistent Client-Side Cross-Site Scripting in the Wild", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] distinguished theoretically taintable flows from exploitable ones, then split exploitability by attacker model (293 network / 65 web of 418). Khodayari et al. [11Khodayari, Soheil; Pellegrino, Giancarlo (2023): "It's (DOM) Clobbering Time: Attack Techniques, Prevalence, and Defenses", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]: 9,467 flows on 491 sites, but 44 websites with a proof-of-concept. Chehade et al. [6Chehade, Saiid El Hajj; Hantke, Florian; Stock, Ben (2025): "403 Forbidden? Ethically Evaluating Broken Access Control in the Wild", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]: 30 endpoints on 15 sites looked improper; 19 vulns on 7 sites were confirmed so they would not notify incorrectly.

A full-text probe for false positive hits 25 of 30 wild papers; manually confirm/verify/inspect/analyse hits 20 of 30. Those are upper bounds on the words, not a confirmation-rate. The rate lives in the paper's own numerator/denominator pair. Copy that pair from the same sentence.

ZAP is ZAP by Checkmarx as of 2024-09-24, still Apache-2.0.2) Nuclei lives at projectdiscovery/nuclei (not archived, 2026-08-27) with templates in nuclei-templates. This corpus's full-text union of nuclei/nikto/w3af/openvas is 24 papers. Do not build a measurement around them.

Dated methods

Method When it was current in this corpus Status in 2026
Black-box scanners on known web apps (Bau et al.) [4Bau, Jason; Bursztein, Elie; Gupta, Divij; Mitchell, John C. (2010): "State of the Art: Automated Black-Box Web Application Vulnerability Testing", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] 2010 lab comparison Historical as “state of the art”. The reflected-vs-stored detection gap is still the thing to measure.
Chromium XSS Auditor / XSS Filter as a defence to evaluate against [3Lekies, Sebastian; Stock, Ben; Johns, Martin (2013): "25 Million Flows Later: Large-scale Detection of DOM-based XSS", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] 2013 (300 of 701 domains still susceptible with the auditor on) Removed in Chrome 78 (2019).3) Do not report Auditor bypasses as a 2026 result.
Taint-tracking a stock or patched Chromium on a ranking list [3Lekies, Sebastian; Stock, Ben; Johns, Martin (2013): "25 Million Flows Later: Large-scale Detection of DOM-based XSS", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)] [2Steffens, Marius; Rossow, Christian; Johns, Martin; Stock, Ben (2019): "Don't Trust The Locals: Investigating the Prevalence of Persistent Client-Side Cross-Site Scripting in the Wild", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] 2013–2019, still the live-web method Current, in Foxhound / PanoptiChrome / 2025–2026 DOM-gadget papers. Report the browser pin and which sources/sinks were on.
SameSite cookies as CSRF mitigation [14Khodayari, Soheil; Pellegrino, Giancarlo (2022): "The State of the SameSite: Studying the Usage, Effectiveness, and Adequacy of SameSite Cookies", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] Measured through 2021; Chrome Lax-by-default is Chrome 80 (2020)4) Current and incomplete. State-changing GET and POST-to-GET still exist in that paper's sample.
CVE/Snyk labels on crawled JS libraries 2017 (Lauinger et al., in the 99 as cve) through 2023 bundling papers Answers “known-vulnerable library version present”, not “this origin is exploitable”. Keep it in the cve bucket.
OWASP Top 10 letter for XSS A7 in 2017; folded into A03 Injection in 2021 A05:2025 Injection (XSS is CWE-79 inside it). Broken Access Control is A01:2025. Do not cite A7 as current.

Heuristic-rules is the modal classification method in the 99 (33 of 99, 33.3%), then manual-labelling (28, 28.3%), then dynamic-analysis (19, 19.2%). Those are methods on the conjunction, not on the 30, and a paper can name several.

What to report

  • Population. Ranking list and date (Tranco ID, not “the top 10k”), logged-in or not, and interaction depth in the Interaction vocabulary.
  • Class. Reflected, stored, DOM, persistent-client, CSRF, SOP, clobbering, pollution — not “XSS”.
  • Unit. Flows vs URLs vs origins vs confirmed exploits. If you print two, they must come from the same experiment.
  • Confirmation. Scanner alert, taint flow, payload executed, manual exploit. Chehade et al. [6Chehade, Saiid El Hajj; Hantke, Florian; Stock, Ben (2025): "403 Forbidden? Ethically Evaluating Broken Access Control in the Wild", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] notified only the confirmed 19.
  • Attacker model. Steffens et al. [2Steffens, Marius; Rossow, Christian; Johns, Martin; Stock, Ben (2019): "Don't Trust The Locals: Investigating the Prevalence of Persistent Client-Side Cross-Site Scripting in the Wild", in: Proceedings of the Network and Distributed System Security Symposium. (Link)] split network vs web attacker; collapsing them inflates exploitability.
  • Browser pin. Taint engines disagree when URL-encoding and source sets change; see Foxhound.
  • Ethics and disclosure. Ethics and Notifying websites, not a second copy here.
  • Security — namespace outline; this is the child that owns methods.
  • Ethics — scanning live sites.
  • Notifying websites — what happens after you have a confirmed finding.
  • Foxhound / PanoptiChrome — the current taint browsers.
  • Interaction — why the landing page is a systematically atypical page.
  • JavaScript — script behaviour without an exploitability claim.
  • Headers — CSP/HSTS as crawlable artefacts (still a red link until that item is written).
  • Phishing — cloaking and feeds, not XSS on honest sites.

Methodology and limitations of these figures

Every corpus number above is a paper count from the 5,859-paper extraction, with the denominator in the same sentence. The 99 is the schema conjunction; the 30 is a single-label hand map whose deciding sentence is in scripts/vuln_fold.mjs and is quote-checked against paper.cols.txt (68 exact, 31 partial at a 60% five-word-window threshold, 0 below). Kind-fold residue is 62 of 99, printed. Full-text probes are upper bounds (4 of 5,859 papers have no .cols; none of the 99 are among those 4). 2025–2026 rows are starred. The queries, the unedited report, rejected sources and the review log are on web_vulnerabilities.

[1]
Hantke, Florian; Roth, Sebastian; Mrowczynski, Rafael; Utz, Christine; Stock, Ben (2024): "Where Are the Red Lines? Towards Ethical Server-Side Scans in Security and Privacy Research", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[2]
Steffens, Marius; Rossow, Christian; Johns, Martin; Stock, Ben (2019): "Don't Trust The Locals: Investigating the Prevalence of Persistent Client-Side Cross-Site Scripting in the Wild", in: Proceedings of the Network and Distributed System Security Symposium. (Link)
[3]
Lekies, Sebastian; Stock, Ben; Johns, Martin (2013): "25 Million Flows Later: Large-scale Detection of DOM-based XSS", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)
[4]
Bau, Jason; Bursztein, Elie; Gupta, Divij; Mitchell, John C. (2010): "State of the Art: Automated Black-Box Web Application Vulnerability Testing", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[5]
Son, Sooel; Shmatikov, Vitaly (2013): "The Postman Always Rings Twice: Attacking and Defending postMessage in HTML5 Websites", in: Proceedings of the Network and Distributed System Security Symposium. (Link)
[6]
Chehade, Saiid El Hajj; Hantke, Florian; Stock, Ben (2025): "403 Forbidden? Ethically Evaluating Broken Access Control in the Wild", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[7]
Olsson, Eric; Eriksson, Benjamin; Doupé, Adam; Sabelfeld, Andrei (2024): "Spider-Scents: Grey-box Database-aware Web Scanning for Stored XSS", in: Proceedings of the USENIX Security Symposium. (Link)
[8]
Eriksson, Benjamin; Pellegrino, Giancarlo; Sabelfeld, Andrei (2021): "Black Widow: Blackbox Data-driven Web Scanning", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[9]
Stock, Ben; Johns, Martin; Steffens, Marius; Backes, Michael (2017): "How the Web Tangled Itself: Uncovering the History of Client-Side Web (In) Security", in: 26th USENIX Security Symposium (USENIX Security 17), pp. 971-987. USENIX Association, Vancouver, BC. (Link)
[10]
Kang, Zifeng; Li, Song; Cao, Yinzhi (2022): "Probe the Proto: Measuring Client-Side Prototype Pollution Vulnerabilities of One Million Real-world Websites", in: Proceedings of the Network and Distributed System Security Symposium. (DOI)
[11]
Khodayari, Soheil; Pellegrino, Giancarlo (2023): "It's (DOM) Clobbering Time: Attack Techniques, Prevalence, and Defenses", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[12]
Khodayari, Soheil; Barber, Thomas; Pellegrino, Giancarlo (2024): "The Great Request Robbery: An Empirical Study of Client-side Request Hijacking Vulnerabilities on the Web", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[13]
Kirchner, Robin; Möller, Jonas; Musch, Marius; Klein, David; Rieck, Konrad; Johns, Martin (2024): "Dancer in the Dark: Synthesizing and Evaluating Polyglots for Blind Cross-Site Scripting", in: Proceedings of the USENIX Security Symposium. (Link)
[14]
Khodayari, Soheil; Pellegrino, Giancarlo (2022): "The State of the SameSite: Studying the Usage, Effectiveness, and Adequacy of SameSite Cookies", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[15]
Mirheidari, Seyed Ali; Arshad, Sajjad; Onarlioglu, Kaan; Crispo, Bruno; Kirda, Engin; Robertson, William (2020): "Cached and Confused: Web Cache Deception in the Wild", in: Proceedings of the USENIX Security Symposium. (Link)
[16]
Mirheidari, Seyed Ali; Golinelli, Matteo; Onarlioglu, Kaan; Kirda, Engin; Crispo, Bruno (2022): "Web Cache Deception Escalates!", in: Proceedings of the USENIX Security Symposium. (Link)
[17]
Sabino, Nuno; Cassel, Darion; Abreu, Rui; Adão, Pedro; Bauer, Lujo; Jia, Limin (2026): "DOM-XSS Detection via Webpage Interaction Fuzzing and URL Component Synthesis", in: Proceedings of the Network and Distributed System Security Symposium. (Link)
You could leave a comment if you were logged in.
security/web_vulnerabilities.1787838181.txt.gz · 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