DVWA DOM-Based XSS Exploit
In my previous article of DVWA series I have demonstrated how to exploit Stored XSS
vulnerabilities at low
, medium
and high
security in DVWA Web Application and we have also reviewed the php source code which was running on server. In this article, I will show you how to exploit DOM-Based XSS
vulnerability in the same web application at low, medium and high security, simultaneously by reviewing their php source code. This article is written from very beginners’ point of view, keeping in mind you don’t know anything about DOM-based XSS.
If you have directly reached to this article then I will suggest you to read my previous blog post on DVWA reflected XSS and DVWA stored XSS where I have introduced about XSS vulnerability, why it arises and types of XSS vulnerability. Before we begin to exploit DOM-based XSS in DVWA, let us know about DOM-based XSS vulnerability in more detail.
What is DOM-based XSS vulnerability ?
DOM-based XSS
is a type of XSS vulnerability which arises when any client-side JavaScript takes input from any attacker-controllable source
and passes it without validation into a sink that execute code dynamically
. Most common example of JavaScript source is location.search
, location.href
, document.referrer
& document.URL
and execution sink is document.write()
, document.writeln()
, element.innerHTML
& element.outerHTML
. Before moving further let us know little more about Source and Sink.
Note: DOM-based XSS is all about playing with Source and Executable Sink.
JavaScript Source
Source as the name denotes is something which is responsible for accepting some input. Likewise in JavaScript, a Source
is an object properties like document.location
, document.referrer
, window.name
and even the parameters of the URL which accepts user input
. You can think a source like an input parameter which accepts some input from the user. This source can be present in any HTML form, or any URL of the web page.
Note: For DOM based XSS to occur, input inside the source must be controlled by the attacker.
JavaScript Sink
S
ink
is the reflection point
that eventually executes the malicious JavaScript
injected through the source. You can think a sink like an output (just to remember) which is given by print
, echo
commands (in php). They are some JavaScript functions or location which execute the code entered from the source.
DOM based XSS relies on the fact that, “a client-side JavaScript code has ability to modify HTML DOM object”. Some examples of HTML DOM objects are area, iframe, anchor, etc. You can think a DOM Object as any valid HTML tag which is present in HTML DOM.
HTML DOM
An HTML DOM
is the skeletal structure where all the HTML tags (called elements here) including JavaScript code of an HTML document are arranged in hierarchical order which is called a Document Object Model
. Example of HTML DOM is shown in the below screenshot.
Elements in the above HTML DOM can be modified by any client-side code (like JavaScript) and this property of HTML DOM is responsible of DOM based XSS.
How to Exploit DOM based XSS in general ?
DOM based XSS is different from Reflected XSS
and Stored XSS
because here user input is not reflected in page source. Instead, it is reflected in HTML DOM
and after its successful exploitation, user input becomes the part of that HTML DOM. You can open HTML DOM using Browser Developer tool or simply by pressing F12
on keyboard.
Note: HTML DOM and Page Source both are different things. Don’t get confuse with them.
View-Source Vs HTML DOM
View source
shows the original HTML source of the page or the raw HTML that is unchanged by any client-side scripts (like JavaScript, VBScript). It is the direct response of the HTTP request from the server. On the other hand, theHTML DOM
is the same HTML structure that has been modified by JavaScript.- The
view source
reflects your HTML structure before any JavaScript is loaded and is non editable. On the other hand, theHTML DOM
reflects your HTML structure after the execution of the JavaScript and is editable. - The
view source
will always be the same across all browsers, on the other hand the generatedHTML DOM
might differ as it is an interpretation and render engines are not all the same.
Steps to Exploit DOM based XSS
These are the general steps which have to be followed every time while testing for Reflected DOM-based XSS on any website.
- Input a
unique
string into thesource
(such as location.search, or any input parameter which is accepting user input) and submit it. - Open
browser developer
tools
and search for the inserted string in the HTML DOM. You can useCTRL+F
keyboard shortcut to search your unique string. Inspect the HTML and find where your string appears.Note:
The browser’s “View source” option won’t work for DOM-based XSS testing because it doesn’t show the changes that have been performed in the HTML by JavaScript. - For each location where your string appears within the DOM, just fire your
XSS payload
there. If your inserted payload passed into the executable sinkwithout any validation
or modification then you will definitely get XSS pop up.
Now we have learnt the basics. Let us exploit DOM-based XSS vulnerability in DVWA application at low, medium and high level.
First of all, login
into your DVWA application by default credential admin
: password
or something else which you have set.
Low Level
We will start from low level and will proceed to high level gradually. Click on DVWA security
on left pane to change the difficulty to low
.
Select Security Level to low
and submit
to submit the request. Click on XSS (DOM)
on left pane to select the vulnerability to DOM XSS.
We are in challenge page. Click on Select
button to check how the application is behaving.
On button click it sets the value of default
parameter to English
in the URL.
Since this lab is DOM based XSS so our first step should be to find potential Source
where we can inject our XSS payload. As we have previously learnt, a parameter
in URL can also be an input source. So let us modify the value of default
parameter in the URL with some unique string hello
and check where our input is reflected in HTML DOM and how it is processed.
According to the arrow 2 in the below screenshot document.location.href.substring()
function is our potential source
because it is accepting the user input inside the default
parameter. Arrow 3 indicates document.write()
as our potential sink
because it reflects the entered value from source inside the <option>...</option>
tag. Which means whatever we will input in default parameter will reflect back inside <option>...</option>
tag inside HTML DOM.
We can verify our unique string hello
reflected back inside <option>
tag pointed by arrow 5.
Since our unique string is reflected back in HTML DOM
so let us inject our basic XSS payload <script>alert('DOM XSS')</script>
in place of hello
in default parameter. We can clearly see in the screenshot that our injected payload got executed successfully and we got XSS pop up.
We can verify that after successful execution, our payload became the part of HTML DOM.
Source Code Analysis
There is no any client-side as well as server-side protection present at low level.
Medium Level
Now change the dvwa security to medium
as shown below.
We got the same page as we had in low level challenge. Again, we will follow the same general steps for finding DOM XSS. So, click on Select
button to check how the application in behaving.
Again, English
value is passing in the default
parameter in the URL.
Input any unique string hello
into the source
i.e., inside default
parameter. We can see our input string is reflected in the HTML DOM.
Now replace hello with our basic XSS payload <script>alert()</script>
and after sending the request we found that it redirects us back to the original URL viz. https://localhost/dvwa/vulnerabilities/xss_d/?default=English. Which means we can’t get XSS pop up using this basic payload. Instead, we have to modify the payload manually to exploit it.
But before this let us analyze the source code of medium severity.
Source Code Analysis
Arrow 1 indicates that script
tag is blocked using stripos()
function and arrow 2, indicates that if user enters <script>
tag then it will redirect the user to the location ?default=English
.
Bypass
We can bypass it by breaking the DOM. For this we can use </select>
html tag. We are using closing tag because <select>
tag is already opened. After </select>
tag we can start new html tag. So, our bypass XSS payload can be any one as given below.
</select><svg onload=alert('XSS')>
</select><img src=x onerror=alert('XSS')>
</select><body onload=alert('XSS')>
You can create thousands of XSS payload to bypass this filter.
We can verify that after successful execution our payload became the part of HTML DOM.
High Level
Let us change the DVWA security level to High
as shown below.
Again, we got the same page as we had in low and medium level. Again, we will follow the same general steps for finding DOM XSS. So, click on Select
button to check how the application in behaving. On clicking the Select
button we again found English
is passing as value in the default
parameter in the URL.
Let us input some unique
string hello
in the default parameter and check whether our string appears in the HTML DOM.
This time we are even not allowed to change the value of parameter. If we do, we get redirected to the URL https://localhost/dvwa/vulnerabilities/xss_d/?default=English. But we can see value of the parameter default
passes into the sink document.write()
which reflects inside the <option>
tag in the HTML DOM. So, we can try our basic XSS payload <script>alert()</script>
there.
When I tried to pass our XSS payload into default
parameter it redirected me again to the default URL viz. https://localhost/dvwa/vulnerabilities/xss_d/?default=English. So, here we have to manually build our XSS payload. But before going further let us give a quick view to its source code.
Source Code Analysis
First block checks if any input is given by the user or not. Second block contains 4 allowed or whitelisted languages inside switch
statement. And according to third block, if the input is anything else then it will redirect to the location ?default=English
. That’s why whenever we tried to enter some unique string in default parameter it redirects us to default location.
Bypass
We can bypass it by breaking the DOM. For this we will use &</select>
before our basic XSS payload. We are using &
just to include our payload as there is whitelisting of Languages. Since &
is a logical AND so it will also be treated as valid. And we are using </select>
to break the DOM. You can also use URL separator #
in place of &
. So, our payload can be anyone given below:
English&</select><Svg Onload=alert('XSS')>
English&</select><body onload=alert('XSS')>
English&</select><marquee onstart=alert('XSS')>
English#</select><SvG/OnLoad=alert('XSS')>
# This may not work in all browsers.
We have got a popup which confirms that we have successfully exploited DOM-based XSS vulnerability at High Level
Security. We can verify that after successful execution our payload became the part of HTML DOM.
So, we have successfully exploited DOM-based XSS vulnerability in DVWA web application at low, medium and high security.
Thanks for reading this article on DOM-based XSS. Hope you would have learnt something new from it or have refined your concept on DOM XSS. For any query and suggestion feel free to write us at [email protected].