The DOM-Based Cross-Site Scripting is vulnerability which appears in document object model instead of html page. In a DOM-based XSS attack, the malicious string is not actually parsed by the victim's browser until the website's legitimate JavaScript is executed. But before going into the details of how DOM based xss works, lets first see What is DOM ?
The Document Object Model is a convention for representing and working with objects in an HTML document. Basically all HTML documents have an associated DOM, consisting of objects representing the document properties from the point of view of the browser. Whenever a script is executed client-side, the browser provides the code with the DOM of the HTML page where the script runs, thus, offering access to various properties of the page and their values, populated by the browser from its perspective.
DOM Based XSS is a Cross-site scripting vulnerability that appears in the DOM instead of part of the HTML. In reflective and stored Cross-site scripting attacks we can see the vulnerability payload in the response page but in DOM based cross-site scripting, the HTML source code and response of the attack will be exactly the same, i.e. the payload cannot be found in the response. It can only be observed on runtime or by investigating the DOM of the page.
In DOM-based XSS attack, there is no malicious script inserted as part of the page; the only script that is automatically executed during page load is a legitimate part of the page. The problem is that this legitimate script directly makes use of user input in order to add HTML to the page. Because the malicious string is inserted into the page using innerHTML, it is parsed as HTML, causing the malicious script to be executed.
Lets see an Example of DOM Based XSS :
The below given code accepts and writes user input using JavaScript with the help of DOM.
<html>
<head>
<title>DOM-Based XSS</title>
</head>
<html>
<body>
<script>
var data = location.hash.substring(1);
document.write("User given Data : "+ unescape(data));
</script>
</body>
</html>
When we provide some input to the page, then it will print it on the page through document.write().The client side script modifies the page content dynamically based on the user supplied input in the url. The javascript code location.hash.substring(1); store all the values after # sign in the url and document.write() write all that data into the page without any kind of sanitization on user supplied data. At here everything is done with the help of Document Object Model or DOM. At this point when an attacker puts malicious script as input then the page is also try to write it on the output. For example :
And the malicious script is get executed. And at here also note that the HTTP response sent from the server does not contain the attacker’s payload. The major difference between DOM based XSS and Reflected or Stored XSS flaw is that it cannot be stopped by server-side filters because anything written after the “#” (hash) will never forward to the server.
Conclusion :
The DOM XSS will appear when a source that can be controlled by the user is used in a dangerous sink, for example document.write, element.innerHTML etc. The best way to fix DOM based cross-site scripting is to use the right output method (sink). For example if you want to use user input to write in a <div> element don't use innerHtml, instead use innerText/textContent.
Links :
XSS Basics : Click here
Reflected XSS : Click here
Stored XSS : Click here