DOM-Based XSS
DOM-Based XSS: The Client-Side Threat

DOM-Based XSS: The Client-Side Scripting You Didn’t Expect

Understanding and defending against the stealthiest XSS variant

⚠️ Ethical Note: This guide is for educational purposes only. Only test systems you own or have permission to test.

What is DOM-Based XSS?

DOM-Based Cross-Site Scripting (XSS) is a client-side vulnerability where the attack payload is executed as a result of modifying the DOM (Document Object Model) environment in the victim’s browser. Unlike traditional XSS, the malicious payload never touches the server.

1
User visits malicious URL
Contains crafted parameters that affect DOM
2
Client-side script processes input
JavaScript writes attacker-controlled data to DOM
3
Malicious code executes
In the context of the vulnerable page

Key Differences from Other XSS Types

Type Payload Location Server Involvement
Reflected XSS Server response Payload reflected from server
Stored XSS Server database Payload served from server
DOM-Based XSS Client-side only No server involvement

How DOM-Based XSS Works

Vulnerable Code Example

// URL: https://example.com/page.html#default=<script>alert(1)</script>
const hash = window.location.hash.substring(1);
document.getElementById('message').innerHTML = hash;

Common Sources of DOM-Based XSS

  • document.URL / window.location properties
  • document.referrer
  • window.name
  • localStorage / sessionStorage
  • HTML5 postMessage data

Finding DOM-Based XSS Vulnerabilities

1. Manual Testing Approach

  1. Identify DOM sinks (functions that write to DOM)
  2. Trace back to sources (user-controllable input)
  3. Test if sources flow to sinks without proper sanitization

2. Common Dangerous Sinks

element.innerHTML
document.write()
eval()
setTimeout()
location.href
Function()

3. Testing Payloads

#test=<img src=x onerror=alert(1)>
#default='-alert(1)-'
#redirect=javascript:alert(document.domain)

Advanced DOM-Based XSS Techniques

1. AngularJS Sandbox Escapes

{{constructor.constructor('alert(1)')()}}

2. jQuery Selector Injection

#selector=<img src=x onerror=alert(1)>

3. PostMessage Exploitation

// Malicious page
window.opener.postMessage('<script>alert(1)</script>', '*');

// Vulnerable page
window.addEventListener('message', function(e) {
    document.getElementById('content').innerHTML = e.data;
});

Tools for Detection

Tool Purpose Usage
DOM Invader (Burp) Built-in DOM XSS detection Enable in Burp Browser
DOMinator Pro Browser extension Passive scanning
OWASP ZAP DOM XSS active scan Use DOM XSS scan rule
Manual Testing Browser DevTools Trace data flow

Prevention and Mitigation

1. Safe DOM Manipulation

// UNSAFE
element.innerHTML = userInput;

// SAFE
element.textContent = userInput;
document.createTextNode(userInput);

2. Context-Aware Encoding

  • HTML Context: Use innerText or textContent
  • Attribute Context: Escape quotes and special chars
  • URL Context: Encode with encodeURIComponent()

3. Content Security Policy (CSP)

Content-Security-Policy: script-src 'self'; object-src 'none';
Pro Tip: Use Trusted Types API (Chrome) to prevent unsafe DOM operations entirely.

Real-World Examples

Case 1: jQuery Selector Injection

A popular website used $(location.hash) allowing XSS through crafted hash fragments.

Case 2: AngularJS Client-Side Template

Single Page App evaluated user input as Angular expressions leading to RCE.

Case 3: PostMessage XSS

Chat widget trusted messages from any origin and injected them into DOM.

Conclusion

DOM-Based XSS is particularly dangerous because:

  • It bypasses server-side protections
  • Traditional scanners often miss it
  • The attack happens entirely client-side
Remember: Always validate and sanitize all client-side input before DOM manipulation, regardless of server-side handling.

Further Resources

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *