Today Cross-site Scripting (XSS)
is a well known web application vulnerability among developers, so
there is no need to explain what XSS is. The most important part of a
Cross-site Scripting attack developers should understand is its impact;
an attacker can steal or hijack your session, carry out very successful
phishing attacks and effectively can do anything that the victim can.
DOM Based XSS simply means a Cross-site scripting vulnerability that appears in the DOM (Document Object Model)
instead of part of the HTML. In reflective and stored Cross-site
scripting attacks you 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.
If you send an HTTP request like this http://www.example.com/test.html#, simple enough your JavaScript code will get executed, because the page is writing whatever you typed in the URL to the page with
After the malicious code is executed by page, you can simply exploit this DOM based cross-site scripting vulnerability to steal the cookies of the user or change the page’s behaviour as you like.
Historically, fragment identified a.k.a. hash introduced to simply scroll the HTML page to a certain element however later on it was adopted by JavaScript developers to be used in AJAX pages to keep track of the pages and various other things, mostly referred as hash-bang "#!".
Due to this design anything after hash won’t be sent to the server. This means all server-side protection in the code will not work for DOM Based XSS vulnerabilities. As a matter of fact, any other type of web protections such as web application firewalls, or generic framework protections like ASP.NET Request Validation will not protect you against DOM Based XSS attacks.
What you need to understand though is that DOM XSS will appear when a source that can be controlled by the user is used in a dangerous sink.
So when you see this either you need to do the necessary code changes to avoid being vulnerable to DOM XSS or you need to add encoding accordingly.
Below is a list of sources and sinks which are typically targeted in DOM XSS attacks. Note that this is not a complete list but you can figure out the pattern, anything that can be controlled by an attacker in a source and anything that can lead to script execution in a sink.
It is always a bad idea to use a user-controlled input in dangerous sources such as eval. 99% of the time it is an indication of bad or lazy programming practice, so simply don’t do it instead of trying to sanitize the input.
Finally, to fix the problem in our initial code, instead of trying to encode the output correctly which is a hassle and can easily go wrong we would simply use element.textContent to write it in a content like this:
It does the same thing but this time it is not vulnerable to DOM based cross-site scripting vulnerabilities.
Simple DOM Based Cross-site Scripting Vulnerability Example
Imagine the following page http://www.example.com/test.html contains the below code:
If you send an HTTP request like this http://www.example.com/test.html#, simple enough your JavaScript code will get executed, because the page is writing whatever you typed in the URL to the page with
document.write
function. If you look at the source of the page, you won’t see
because it’s all happening in the DOM and done by the executed JavaScript code.After the malicious code is executed by page, you can simply exploit this DOM based cross-site scripting vulnerability to steal the cookies of the user or change the page’s behaviour as you like.
DOM XSS Vulnerability is a Real Threat
Various research and studies identified that up to 50% of websites are vulnerable to DOM Based XSS vulnerability. Security researchers have already identified DOM Based XSS issues in high profile internet companies such as Google, Yahoo and Alexa.Server Side Filters Do Not Matter
One of the biggest differences between DOM Based XSS and Reflected or Stored XSS vulnerabilities is that DOM Based XSS cannot be stopped by server-side filters. The reason is quite simple; anything written after the "#" (hash) will never be sent to the server.Historically, fragment identified a.k.a. hash introduced to simply scroll the HTML page to a certain element however later on it was adopted by JavaScript developers to be used in AJAX pages to keep track of the pages and various other things, mostly referred as hash-bang "#!".
Due to this design anything after hash won’t be sent to the server. This means all server-side protection in the code will not work for DOM Based XSS vulnerabilities. As a matter of fact, any other type of web protections such as web application firewalls, or generic framework protections like ASP.NET Request Validation will not protect you against DOM Based XSS attacks.
Input & Output so called Source & Sink
The logic behind the DOM XSS is that an input from the user (source) goes to an execution point (sink). In the previous example our source wasdocument.baseURI
and the sink was document.write
. What you need to understand though is that DOM XSS will appear when a source that can be controlled by the user is used in a dangerous sink.
So when you see this either you need to do the necessary code changes to avoid being vulnerable to DOM XSS or you need to add encoding accordingly.
Below is a list of sources and sinks which are typically targeted in DOM XSS attacks. Note that this is not a complete list but you can figure out the pattern, anything that can be controlled by an attacker in a source and anything that can lead to script execution in a sink.
Popular Sources
- document.URL
- document.documentURI
- location.href
- location.search
- location.*
- window.name
- document.referrer
Popular Sinks
- HTML Modification sinks
- document.write
- (element).innerHTML
- HTML modification to behaviour change
- (element).src (in certain elements)
- Execution Related sinks
- eval
- setTimout / setInterval
- execScript
Fixing DOM Cross-site Scripting Vulnerabilities
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
element don’t use innerHtml,
instead use innerText/textContent. This will solve the problem, and it
is the right way to remediate DOM based XSS vulnerbilities.It is always a bad idea to use a user-controlled input in dangerous sources such as eval. 99% of the time it is an indication of bad or lazy programming practice, so simply don’t do it instead of trying to sanitize the input.
Finally, to fix the problem in our initial code, instead of trying to encode the output correctly which is a hassle and can easily go wrong we would simply use element.textContent to write it in a content like this:
Current URL:
document.getElementById("contentholder").textContent = document.baseURI;
Aucun commentaire:
Enregistrer un commentaire