Day 3. The 100-Day Bug Bounty Challenge: Understanding DOM-Based XSS (Cross-Site Scripting)
Welcome to Day 3 of my 100-day bug bounty challenge! Today, we’re diving into a more advanced form of XSS: DOM-Based Cross-Site Scripting (DOM XSS). This type of vulnerability originates in the client-side code of web applications and can be tricky to detect. Let’s explore what it is, how it works, and examine three real-life examples.
What is DOM-Based XSS?
DOM-Based XSS occurs when the web application’s client-side JavaScript processes user input in an insecure way, leading to malicious scripts being executed in the browser. Unlike reflected or stored XSS, the server does not directly process or reflect the malicious input; instead, the issue lies entirely in the Document Object Model (DOM).
In simpler terms:
- User input is handled by the browser (via JavaScript).
- If the input isn’t sanitized, malicious scripts can be executed directly in the user’s browser.
How DOM XSS Works
- The attacker identifies a vulnerable JavaScript function or method (e.g.,
innerHTML
,document.write
,eval
). - The attacker crafts a malicious payload that the browser processes unsafely.
- The malicious script executes in the victim’s browser, often leading to cookie theft, session hijacking, or phishing attacks.
Example 1: DOM XSS in a Search Bar
Imagine a website with a search bar that processes the q
parameter from the URL and displays it dynamically on the page:
Vulnerable Code:
var searchQuery = new URLSearchParams(window.location.search).get('q');
document.getElementById('search-result').innerHTML = `You searched for: ${searchQuery}`;
If an attacker crafts the following URL:
https://example.com/search?q=<script>alert('XSS')</script>
When the victim clicks this link:
- The JavaScript code takes the
q
parameter from the URL. - The
innerHTML
method renders it directly without sanitization. - The malicious
<script>
tag is executed in the browser, triggering the alert box.
Impact:
- The attacker can execute arbitrary scripts, such as stealing session cookies or defacing the site for anyone who clicks the malicious link.
- The vulnerability only exists on the client side, making it harder to detect with traditional server-side analysis tools.
Fix:
Replace innerHTML
with a safer alternative like textContent
:
var searchQuery = new URLSearchParams(window.location.search).get('q');
document.getElementById('search-result').textContent = `You searched for: ${searchQuery}`;
Example 2: DOM XSS in a URL Fragment
Many applications use URL fragments (the part of the URL after #
) to track state or user actions. If improperly handled, these fragments can lead to DOM XSS.
Vulnerable Code:
var hash = window.location.hash.substring(1);
document.getElementById('content').innerHTML = hash;
If the attacker crafts the following URL:
https://example.com/#<img src=x onerror=alert('XSS')>
When the victim visits this URL:
- The browser processes the URL fragment.
- The JavaScript code assigns it to
innerHTML
. - The malicious
<img>
tag executes theonerror
payload, triggering the alert box.
Impact:
- Attackers can inject scripts that steal cookies, modify page content, or perform phishing attacks.
- Since URL fragments are not sent to the server, this attack bypasses server-side input validation.
Fix:
Use textContent
instead of innerHTML
:
var hash = window.location.hash.substring(1);
document.getElementById('content').textContent = hash;
Example 3: DOM XSS in a Client-Side Redirect
Some applications use JavaScript to redirect users based on input parameters, which can be exploited if not validated.
Vulnerable Code:
var redirectUrl = new URLSearchParams(window.location.search).get('redirect');
window.location = redirectUrl;
If the attacker crafts the following URL:
https://example.com/?redirect=javascript:alert('XSS')
When the victim clicks the link:
- The
redirect
parameter is passed towindow.location
. - The browser interprets the
javascript:
scheme and executes the alert payload.
Impact:
- Attackers can redirect users to malicious sites.
- They can also execute JavaScript directly in the browser, stealing sensitive data or hijacking sessions.
Fix:
Validate the redirect
parameter to ensure it only contains safe URLs:
var redirectUrl = new URLSearchParams(window.location.search).get('redirect');
if (redirectUrl.startsWith('https://example.com')) {
window.location = redirectUrl;
} else {
console.error('Invalid redirect URL');
}
How to Test for DOM XSS
- Inspect Client-Side Code: Look for JavaScript functions that handle user input (e.g.,
innerHTML
,document.write
,eval
,window.location
) - Craft Malicious Payloads:
<script>alert('XSS')</script>
"><img src=x onerror=alert('XSS')>
javascript:alert('XSS')
3. Analyze Execution:
- Use browser developer tools to monitor DOM changes and script execution.
- Test different payloads in URL parameters, URL fragments, or cookies.
4. Use Automated Tools:
- Tools like Burp Suite or OWASP ZAP can help detect DOM XSS.
Mitigation and Prevention
To prevent DOM XSS, developers should:
- Avoid Dangerous Methods:
- Replace
innerHTML
withtextContent
orinnerText
. - Avoid using
eval
ordocument.write
.
2. Sanitize User Input:
- Use libraries like DOMPurify to clean inputs before rendering them.
3. Validate URL Parameters:
- Ensure all parameters are safe and expected.
4. Implement a Content Security Policy (CSP):
- Restrict the sources of executable scripts.
Tools to Help You
- Burp Suite: Test for client-side vulnerabilities in JavaScript.
- OWASP ZAP: Automated scanning for XSS.
- DOM Invader: A browser extension to identify and exploit DOM XSS.
- Browser Developer Tools: Inspect how input is processed and rendered in the DOM.
Bonus
- Learning Resources: (click on the Text to redirect)
2. Payloads Cheat-sheet:
3. Reports:
Conclusion
DOM-Based XSS is a powerful attack vector that exploits client-side JavaScript vulnerabilities. By understanding how it works and testing for it effectively, you can identify and report these issues responsibly. Always focus on educating developers about safe coding practices to prevent such vulnerabilities.
That’s it for Day 3! Tomorrow, we’ll explore another vulnerability. If you have any questions or insights about DOM XSS, feel free to share them.
Happy hunting, and stay ethical!