In this section, we'll describe DOM-based cross-site scripting, explain how to find DOM XSS vulnerabilities, spell out how to exploit DOM-based XSS with different sources and sinks, and explain reflected and stored variants of DOM XSS vulnerabilities.
The majority of DOM-based cross-site scripting vulnerabilities can be found quickly and reliably using Burp Suite's web vulnerability scanner. To test for DOM-based cross-site scripting manually, you generally need to use a browser with developer tools, such as Chrome. You need to work through each available source in turn, and test each one individually.
For each location where your string appears within the DOM, you need to identify the context. Then based on this context, you need to refine your input to see how it is processed. For example, if your string appears within a double quoted attribute then try to inject double quotes in your string to see if you can break out of the attribute.
Note that browsers behave differently with regards to URL-encoding, Chrome, Firefox, and Safari will URL-encode location.search and location.hash, while IE11 and Microsoft Edge (pre-Chromium) will not URL-encode these sources. If your data gets URL-encoded before being processed, then an XSS attack is unlikely to work.
In principle, an application is vulnerable to DOM-based cross-site scripting if there is an executable path via which data can propagate from source to sink. In practice, different sources and sinks have differing properties and behavior that can affect exploitability, and determine what techniques are necessary. Additionally, the application's scripts might perform validation or other processing of data that must be accommodated when attempting to exploit a vulnerability. There are a variety of sources and sinks that are relevant to DOM-based vulnerabilities.
The document.write sink works with script elements, so you can use a simple payload such as:
document.write('... <script>alert(document.domain)</script> ...');
The innerHTML sink doesn't accept script elements on any modern browser, nor will svg onload events fire. This means you will need to use alternative elements like img or iframe. Event handlers such as onload and onerror can be used in conjunction with these elements. For example:
element.innerHTML='... <img src=1 onerror=alert(document.domain)> ...'
Some pure DOM-based vulnerabilities are self-contained within a single page. If a script reads some data from the URL and writes it to a dangerous sink, then the entire vulnerability exists within that page.
In other cases, the vulnerability involves some server-side reflection or storage of the input that is handled unsafely by the client-side script: