Unravelling the Web: A Penetration Tester’s Perspective on DOM-based XSS


As a seasoned Penetration Tester who specialises in Web Application testing, the one vulnerability that continually surfaces is reflected and stored Cross-Site Scripting (XSS) through common vectors like forms and headers. Yet, one of the less explored and frequently dreaded vulnerabilities is Document Object Model (DOM)-Based XSS. In this blog post, we delve into the world of DOM-based XSS, unravelling its nature, nuances, and providing effective strategies to fortify against this stealthy threat. 

What is DOM-Based XSS? 
Before we begin understanding DOM-Based XSS, we need to all be on the same page with what the name is comprised of: 

What is XSS? 
Cross-Site Scripting (XSS) is a security vulnerability that occurs when an attacker injects malicious scripts into web pages viewed by other users. These scripts are usually written in JavaScript but can be in other scripting languages as well. When a victim visits a web page containing the malicious script, the script executes within the context of the user’s browser, allowing the attacker to steal sensitive information, manipulate the appearance of the page, or perform other malicious actions on behalf of the user. 

What is DOM?
The Document Object Model (DOM) is a programming interface for web documents. It represents the document’s structure as a tree of objects, where each object corresponds to a part of the document, such as elements and attributes. In the context of web development, the DOM is crucial for dynamically accessing and manipulating the content, structure, and style of a document. For example, JavaScript can be used to change the content of a webpage, modify its structure, or respond to user actions. 

Understanding DOM-based XSS 
DOM-based XSS differs from traditional XSS by exploiting the Document Object Model (DOM) instead of manipulating the HTML. This vulnerability arises when the client-side scripts dynamically manipulate the DOM based on user inputs, paving the way for malicious actors to inject and execute arbitrary code in the user’s browser. 

The Anatomy of an Attack 
1. User-Controllable Data: 
Attackers exploit endpoints where user inputs directly impact the DOM, such as URL parameters or form fields. 

Image 1
Image 2

2. Script Injection: 
 Malicious scripts are injected, often in the form of JavaScript code, into the DOM. Paying attention to the element that the input is within. As shown below we need to break out of the img attribute and then inject the payload.

Image 3

3. Execution in User’s Browser: 
 When the manipulated script is executed, it runs in the user’s browser, compromising their session via cookie hijacking whereby the payload requests the attacker’s http server that is listening, stealing sensitive data, or facilitating further attacks. In this example you can see that the document.domain element was requested and returned. 

Image 4

Defending Against DOM-based XSS 
1. Input Validation and Sanitisation: 
 Implement rigorous input validation on both client and server sides. Sanitise user inputs by stripping or encoding any potentially harmful characters. 
2. Context-Aware Output Encoding: 
 Ensure proper output encoding for user-generated content based on its context. Different contexts (HTML, JavaScript, URL, etc.) demand specific encoding techniques. 
3. Content Security Policy (CSP): 
 Implement a robust CSP to restrict the sources from which resources can be loaded, mitigating the impact of injected scripts. 
4. Use Strict Mode: 
Enable JavaScript’s strict mode to catch common programming errors and make it harder for attackers to exploit vulnerabilities. 
5. Regular Security Audits: 
Regularly audit and review your codebase for potential vulnerabilities. Automated tools combined with manual inspection can unveil hidden threats. 
6. Educate Development Teams: 
Empower your development teams with security best practices. Training them to recognise and avoid potential pitfalls can be as crucial as implementing technological defences. 
7. Monitoring and Incident Response: 
 Set up robust monitoring systems to detect unusual activities and promptly respond to incidents. Timely response can minimise the damage caused by a successful attack. 

In the ever-evolving landscape of web security, DOM-based XSS remains a formidable adversary. By understanding the intricacies of this vulnerability and adopting a holistic approach to defence, developers and security professionals can strengthen their armour against potential exploits. Remember, an effective defence is a combination of technology, awareness, and a proactive mindset. Stay vigilant, stay secure. 

Simon cundy

Written by Simon Cundy
Simon Cundy serves as the Red Team Leader at norm., spearheading efforts to fortify cyber security resilience. His extensive expertise is highlighted by a impressive collection of accreditations, notably as a distinguished member of the CyberScheme Team. Simon’s credentials further showcase certifications as a Certified Red Team Operator and a Certified Azure Red Team Professional. As a versatile and multi-disciplinary tester, he specialises in Web Application, infrastructure, mobile application, and Red Teaming.