DOM is a W3C (World Wide Web Consortium) standard. It is a platform independent interface that allows programs and scripts to dynamically access and modify the structure of an document. The document can be HTML, XHTML or XML.
Let us apply the above definition practically:
Before modifying element using DOM: In the below figure, we have displayed an HTML element’s value using document.write function
We have changed it to ‘Changed!’. And the code responsible for it is:
document.getElementById("demo").innerHTML = "Changed!";
XSS also called as Cross Site Scripting is one of OWASP Top 10 attacks which results in client side code execution. Using XSS, an attacker can carry out attacks against the application users such as stealing cookies, creating a Trojan login form etc. There are 3 types of XSS:
Unlike Reflected and Stored XSS, payload for DOM based XSS does not get delivered to the victim with server response. In fact, the payload never goes to the server within request. After server’s response reaches the browser, the malicious payload gets executed in an unexpected way by modifying the browsers DOM. The following picture represents the attack scenario:
In the demo, we have a web app that has a DOM based XSS vulnerability. It has a URL based redirection functionality which will be of our interest.
1. User clicks on this link: http://127.0.0.1/domxss/domxss.php#http://securelayer7.net
2. A GET Request goes to http://127.0.0.1/domxss/domxss.php. The request does not contain the URL written after # (i.e. https://securelayer7.net). Browsers consider it to be a client side data and do not send it as a part of request. However, browsers will process it after the response is received.
3. Response is received and the following HTML code gets loaded in web page.
The data after # is fetched dynamically and is passed to window.open to perform the required redirection and user gets redirected to https://securelayer7.net
And it executes whatever is written after # in the URL.
So, the partially patched code is:
So, now if an attacker tries to use the earlier payload then, he will see the following page:
However, the above fix can be bypassed by crafting the URL which starts from ‘http:’ and directs victim to a link which contains the malicious script. So, the new payload becomes:
So, we cannot rely on that fix. This means that use of black listing or regular expression has failed. So, the correct fix would be input validation by comparing with absolute value of URL. In our case the following URL is legitimate:
So, the completely patched code is:
Now if a user tries to enter any URL of his choice, then it will be rejected and only the one given URL will be accepted. The legitimate page after redirection will look like:
So, we have seen how to find, exploit and patch DOM based XSS vulnerability. Thanks for reading. I hope you have enjoyed it.