AutoDetection & Exploitation of DOM Clobbering Vuln at Scale

Zhengyu Liu, Jianjia Yu

DEF CON 33 · Day 1 · Main Stage

Overview

DOM Clobbering is a class of web vulnerability that has existed since browser developers decided that HTML elements with id or name attributes should be accessible as properties on the global win

Watch on YouTube · Slides

Visual summary for AutoDetection & Exploitation of DOM Clobbering Vuln at Scale by Zhengyu Liu, Jianjia Yu
Visual summary for AutoDetection & Exploitation of DOM Clobbering Vuln at Scale by Zhengyu Liu, Jianjia Yu

Key moments

  1. 1:24 day hunting results and show how we turn those HTML injection into the end to end...
  2. 7:19 uh hawk finds a vulnerable gadgets from the Google client A
  3. 13:09 We categorize the source into two tabs.
  4. 24:48 insight here is that we start from small and then connect those and finally concrete...
  5. 27:01 So therea our cases includes uh modern web bundlers like webpack, rspack, vite,...
  6. 32:31 code execution if we construct our payload as this HML HML collection.
  7. 43:44 day gadgets found by our tool hawk.

The DOMino Effect: Automated Detection and Exploitation of DOM Clobbering Vulnerabilities at Scale

Speakers: Zhengyu Liu, Jianjia Yu Conference: DEF CON 33 YouTube: https://www.youtube.com/watch?v=JL2PT1Dac3g Slides: https://media.defcon.org/DEF%20CON%2033/DEF%20CON%2033%20presentations/Zhengyu%20Liu%20Jianjia%20Yu%20-%20The%20DOMino%20Effect%20Automated%20Detection%20and%20Exploitation%20of%20DOM%20Clobbering%20Vulnerability%20at%20Scale.pdf

Overview

DOM Clobbering is a class of web vulnerability that has existed since browser developers decided that HTML elements with id or name attributes should be accessible as properties on the global window and document objects. The mechanism is intentional — it is specified behavior from the HTML standard — but it creates a naming collision between the DOM and JavaScript variables that attackers can exploit. If a JavaScript library looks up window.config and an attacker can inject a DOM element with id="config", the library gets an HTML element instead of the expected JavaScript object. What happens next depends entirely on what the library does with the value.

At DEF CON 33, researchers Zhengyu Liu and Jianjia Yu presented Hulk — the first dynamic analysis tool to automatically detect DOM Clobbering gadgets and generate working exploits end-to-end. Their evaluation against the Tranco Top 5,000 websites discovered 497 zero-day exploitable DOM Clobbering gadgets, with vulnerabilities confirmed in Webpack, Vite, Rollup, Astro, Google Client API, and dozens of other widely deployed libraries. A parallel study of HTML Injection vulnerabilities identified over 200 affected websites. The combination of gadgets and injection points produced 12 complete end-to-end exploits — 11 XSS and 1 CSRF — in high-profile applications including Jupyter Notebook, JupyterLab, HackMD.io, and Canvas LMS. The research produced 19 CVE identifiers.

Background

▶ Watch: day hunting results and show how we turn those HTML injection into the end to... (1:24)

What Is DOM Clobbering?

The HTML specification defines a feature called named element lookups: when JavaScript code accesses an undefined property on window or document, the browser searches the current document's DOM for an element whose id or name attribute matches the property name and returns that element instead of undefined. This behavior is primarily a legacy compatibility mechanism, dating to early browser implementations and preserved for backward compatibility.

The attack consequence is straightforward: if an attacker can inject arbitrary HTML into a page — through an HTML injection vulnerability in a form field, a comment, a rich text editor, or a Markdown renderer — they can define HTML elements that intercept JavaScript variable lookups. When the JavaScript code subsequently dereferences the variable, it receives a DOM element (or a collection of DOM elements, or a DOM element's string representation) rather than the intended value.

Depending on what the code does with that value, consequences range from nothing to full XSS (Cross-Site Scripting). When the clobbered value flows into a sink like eval(), setTimeout(), innerHTML, or a <script src> attribute, an attacker-controlled string can execute arbitrary JavaScript in the victim's browser.

Prior Work and Its Limitations

DOM Clobbering was formally introduced to the security research community by Gareth Heyes in 2013. A notable 2023 paper from Oakland ("It's Clobbering Time") catalogued 30,000+ clobbering markup payloads across five technique categories and identified gadgets in popular libraries using static analysis.

Static analysis, however, struggles with modern JavaScript codebases. Production JavaScript is minified, bundled, and heavily aliased — the static data flow that connects a clobberable source to an exploitable sink is often obscured by dynamic property lookups, closure capturing, and module bundler transformations. Previous attempts using static analysis, Invader (a canary-based approach), and generic fuzzing all produced incomplete coverage or false positives that required manual validation.

Liu and Yu's key insight is that dynamic analysis, applied carefully to a live browser executing real JavaScript, can track data flow in the actual runtime environment where the vulnerability matters — circumventing the static analysis problem at the cost of needing a more sophisticated taint tracking implementation.

Key Findings

▶ Watch: We categorize the source into two tabs. (13:09)

Scale of Vulnerable Deployments

Evaluating the Tranco Top 5,000 websites using Hulk revealed:

  • 497 zero-day exploitable DOM Clobbering gadgets across the measured sites
  • Affected libraries span bundlers (Webpack, Rspack, Vite, Rollup, Tisa, Polyfuse), analytics services (Plausible Analytics), development APIs (Google Client API), frameworks (Astro), and core utility libraries (Prism.js, Page.js, Findjax v2/v3)
  • Webpack averaged 1.27 bundled scripts per site in the Tranco Top 1,000 — making Webpack gadgets effectively present on a large fraction of the measured web

HTML Injection

A parallel manual analysis of HTML injection vulnerabilities found:

  • 187 HTML injection vulnerabilities across tested websites
  • 12 vulnerable editors and client-side libraries with HTML injection capabilities
  • Over 200 websites total with accessible HTML injection entry points

End-to-End Exploits

Combining gadgets with HTML injection vulnerabilities produced 12 complete exploit chains:

  • 11 exploits achieving XSS
  • 1 exploit achieving CSRF
  • High-profile targets include Jupyter Notebook, JupyterLab, HackMD.io, and Canvas LMS

CVE Assignments

The disclosure process resulted in 19 CVE identifiers assigned to date, covering the affected libraries and applications. All mentioned vendors acknowledged and patched the issues following coordinated disclosure.

Technical Deep Dive

▶ Watch: insight here is that we start from small and then connect those and finally c... (24:48)

Hulk: Dynamic Taint Analysis for DOM Clobbering

Hulk operates in three stages: taint tracking, exploit generation, and validation replay.

Stage 1: Dynamic Taint Analysis

Hulk instruments the target website's JavaScript using code rewriting (via Esprima for parsing and Jest for transformation infrastructure). This approach avoids browser-specific modifications and works across browsers. The instrumentation tracks taint — a marker attached to values that originate from clobberable DOM sources — as those values flow through JavaScript operations.

Sources tracked:

  • document.links, document.scripts: DOM collections whose members are clobberable via id and name attributes
  • Window property lookups: When window.something is accessed and something is undefined, the browser performs a named element lookup — this is the canonical clobbering entry point

Taint propagation:

  • For object values: Hulk attaches non-enumerable taint properties that survive property access chains without polluting normal object behavior
  • For primitive values (strings, numbers) and undefined: Hulk uses wrapper objects that carry taint metadata alongside the wrapped value
  • Built-in JavaScript operations (string concatenation, type coercion, array operations) and browser APIs are handled through an extensible set of taint propagation handlers

The analysis output is a taint dependency graph: a record of which operations transformed which tainted values, including both the concrete value observed at runtime and whether that value is attacker-controlled. This graph is the foundation for the exploit generation stage.

Stage 2: Symbolic DOM Constraint Solving

Given a taint dependency graph showing that an attacker-controlled value from a clobberable source flows to an exploitable sink, Hulk's second stage constructs a working HTML payload that achieves the exploitation.

The researchers systematized DOM Clobbering exploitation into four stages, building a formal model for each:

Stage 1 — Initial Clobbering: Creating a DOM element whose id or name attribute matches the JavaScript property lookup key. This is the entry point for all DOM Clobbering attacks.

Stage 2 — Advanced Clobbering: Loading structured data from the DOM into the program. Techniques include:

  • Multiple elements to simulate array-like collections (leveraging document.getElementsById semantics)
  • Nested window proxy clobbering for deeply nested property access chains
  • DOM property exploitation (e.g., previousSibling, parentElement) for relational access

Stage 3 — DOM-to-String Coercion: Getting the DOM element or collection to produce an attacker-controlled string value. Techniques include:

  • Using <a> or <area> elements whose href attribute contains a URL — type coercion of these elements produces the full URL as a string (combined with a <base> element for relative URL manipulation)
  • Attribute name collisions (e.g., <input> elements have a value attribute accessible as a string property)
  • Getter-based coercion through JavaScript's valueOf/toString dispatch

Stage 4 — String-to-Sink Transformation: Tracking all transformations (regex processing, substring extraction, URL parsing, concatenation) that the clobbered value undergoes before reaching the sink (e.g., eval, setTimeout, innerHTML, script.src).

Hulk represents the required DOM structure symbolically, then solves the combined constraints from all four stages to produce a minimal, concrete HTML payload. The constraint system handles property key requirements, attribute value constraints, structural requirements (sibling relationships, collection membership), and type coercion requirements simultaneously.

Stage 3: Replay Validation

The generated payload is injected into the target page and the instrumented JavaScript re-executes. Hulk checks whether a "canary" value embedded in the payload reaches the target sink. This binary validation step filters out cases where the constraint solver produces a technically valid payload that fails at runtime due to conditions not captured in the taint graph.

Demo / PoC

▶ Watch: code execution if we construct our payload as this HML HML collection. (32:31)

Webpack Gadget

Webpack, present on a significant fraction of the web, contains a gadget exploitable via document.currentScript. When Webpack's runtime attempts to identify the current executing script's source URL, it accesses document.currentScript. In browsers that do not implement document.currentScript natively (or in certain loading contexts where it returns null), Webpack falls back to document.scripts lookups.

An attacker with HTML injection capability can inject:

This element, clobbering document.currentScript, causes Webpack's module loading infrastructure to load the attacker-controlled script URL. The exploit works across all sites using Webpack's dynamic import features where document.currentScript is accessible.

Astro Framework Gadget

Astro's client-side hydration script checks document.scripts as an array-like collection using Array.from(). It then iterates the collection checking for scripts that lack a data-astroexec dataset attribute and lack an explicit type attribute. For any such script found, it executes the script's innerHTML as JavaScript.

An attacker injects an HTMLCollection (multiple <script> elements without type attributes):

When accessed as document.scripts, this collection satisfies Astro's iteration conditions. The innerHTML of the second element — alert(1) — is executed as JavaScript.

Google Client API Gadget (HackMD.io)

HackMD.io uses Google Client API for authentication. The Google Client API script accesses document.scripts to locate its own script tag and retrieve configuration. An attacker who can inject HTML (via HackMD's iframe name attribute — an HTML injection vector in the editor) can clamp the document.scripts lookup to a controlled <script> element that contains attacker-controlled configuration JSON. The API then passes this configuration through a new Function() constructor, achieving XSS.

MathJax v2 Gadget (Jupyter Notebook)

Jupyter Notebook includes MathJax v2 for mathematical notation rendering. MathJax's configuration system checks window.mathjax for a configuration object. If present, it uses the object's src property to load an extension script. The src property is processed through type coercion — MathJax concatenates it with a base URL string.

An attacker injects:

When JavaScript coerces the <a> element to a string (via its URL-formatted href), the result is //attacker.com/ — which, when concatenated with MathJax's expected base URL, produces a URL that loads the attacker's extension script as a <script src> element.

Defensive Implications

▶ Watch: day gadgets found by our tool hawk. (43:44)

For Library and Framework Developers

  • **Avoid relying on window. or document. property lookups for configuration or module location**: These paths are clobberable. Use explicit module imports, constructor parameters, or data-* attributes on known script elements.
  • Validate types before using dynamic lookups: If window.config is expected to be a plain JavaScript object, explicitly check typeof window.config === 'object' && window.config !== null && !(window.config instanceof Element) before using it.
  • Replace document.currentScript fallbacks with more robust alternatives that cannot be clobbered.
  • Audit document.scripts access patterns: Any code that iterates document.scripts and acts on script content or attributes is a potential DOM Clobbering sink.

For Application Developers

  • Implement strict HTML sanitization: HTML injection is the trigger for almost all practical DOM Clobbering exploits. Libraries like DOMPurify, configured to strip id and name attributes from injected HTML, significantly reduce the attack surface. Note that disabling id and name entirely may affect accessibility and functionality.
  • Use a strong Content Security Policy (CSP): CSP with script-src restrictions that prevent loading scripts from arbitrary URLs will block many DOM Clobbering gadget payloads that attempt to load external scripts. A nonce-based CSP that only allows scripts with specific nonces provides stronger protection.
  • Test rich text editors and Markdown renderers: These are the most common HTML injection entry points in modern web applications. Verify that user-supplied content cannot introduce DOM elements with id or name attributes that would shadow JavaScript variables.

For Browser Vendors

Firefox is reportedly considering a change to disable the named property lookup mechanism on document object lookups, which would eliminate the primary DOM Clobbering entry point at the browser level. The Hulk researchers' findings are cited as part of the evidence motivating this consideration. If implemented, this change would be the most comprehensive mitigation available.

Key Takeaways

  1. DOM Clobbering is a widely exploited code-reuse attack class affecting hundreds of top-ranked websites and mainstream JavaScript libraries.
  2. Static analysis consistently fails to detect DOM Clobbering gadgets in minified, bundled production JavaScript; dynamic taint analysis is required.
  3. Hulk, the first end-to-end automated detection and exploitation tool for DOM Clobbering, discovered 497 zero-day gadgets in the Tranco Top 5,000 sites.
  4. Gadgets in ubiquitous infrastructure — Webpack, Google Client API — propagate the vulnerability to any application that uses these libraries without modification.
  5. HTML injection is the practical trigger for DOM Clobbering exploits; Markdown renderers, rich text editors, and form fields are common injection entry points.
  6. Complete attack chains were demonstrated in Jupyter Notebook, JupyterLab, HackMD.io, and Canvas LMS, achieving XSS and CSRF.
  7. The research produced 19 CVEs; all affected vendors patched following disclosure.
  8. Firefox is considering a browser-level fix that would remove the named property lookup mechanism on document, which would eliminate the primary entry point for this class of attack.

About the Speakers

Zhengyu Liu and Jianjia Yu are PhD students and web security researchers whose work focuses on web attack primitives, client-side security, and automated vulnerability analysis. This research was conducted in collaboration with Tai Kong and a colleague referred to in the talk — all members of a research group at their university with a focus on web security and software security.

The Hulk tool, the full dataset of discovered gadgets, and the research paper are open-sourced and publicly available via a QR code referenced in the DEF CON 33 presentation. The work represents a systematic expansion of prior DOM Clobbering research (particularly the 2023 Oakland "It's Clobbering Time" paper) from detection methodology to fully automated end-to-end exploit generation, deployed at a scale — 5,000 websites — not attempted by previous work in this area.

Reviews

Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT

Liu and Yu built Hulk, the first end-to-end dynamic taint analysis tool for DOM Clobbering, and ran it against the Tranco Top 5,000 to find 497 zero-day exploitable gadgets — including Webpack, Google Client API, and Astro — generating 19 CVEs and 12 complete exploit chains including XSS in Jupyter Notebook, JupyterLab, HackMD.io, and Canvas LMS.

Heather Calloway (CISO) — STRONG ACCEPT

Zhengyu Liu and Jianjia Yu built Hulk, the first tool to automatically detect DOM Clobbering gadgets and generate working exploits end-to-end. Against the Tranco Top 5,000, they found 497 zero-day exploitable gadgets in libraries including Webpack, Vite, Google Client API, and Astro — then combined them with HTML injection vulnerabilities to produce 12 working XSS and CSRF exploits in Jupyter Notebook, HackMD.io, and Canvas LMS. 19 CVEs. Vendors patched.

→ Top-rated talks at DEF CON 33

All talks from DEF CON 33