In an earlier blog post we looked at a basic introduction to Cross-Site Scripting or “XSS”, and how to prevent it when developing in-house web applications.
In that article we mainly focused on outlining how a basic form of XSS known as “Reflected XSS” works, because this is the simplest form to explain, as well as the form that is most commonly encountered, and the simplest for an attacker to exploit.
We also mentioned a variant known as “DOM XSS” in that article but didn’t dig further into exactly how it worked – that’s what we’re going to look at today. Strictly speaking, this form of XSS is more broadly referred to as “Client-Side XSS”.
“DOM” stands for “Document Object Model” and although you may not have heard of it, it underpins how every web browser interprets and renders web pages that are received from the server. It represents a web page as a document so that client-side scripting languages can change the structure, style, and content. Typically, web pages are transmitted and presented as HTML content, along with instructions on how associated static content should be rendered and displayed. However, this representation can all be manipulated and changed through client-side code talking to the programming interface exposed by the DOM.
The DOM is represented as an object-orientated tree structure of nested elements known as nodes. Each node represents an individual page element, and the DOM allows unique identification of each element in the tree via a dot-delimited and hierarchical “address”. For example a form may have the name “userDetails” and be addressable therefore as “document.userDetails”.
As a brief refresher, both reflected and stored XSS are ultimately “executed” on the client-side but rely on flaws in the handling of input or output processed by the server. That is, there is an input handler on the server somewhere that fails to correctly maintain the separation between executable code and user-provided data under certain conditions (a process that is typically ensured via measures such as robust input validation. The flawed input handler allows an attacker to send malicious data that causes the server to return or “reflect” unsanitized responses back to the client containing the attacker’s input as injected code, which the user’s browser then faithfully executes.
In server-side XSS, input is sent to the web server via HTTP requests using HTTP verbs (methods) such as GET or POST, with the user-supplied input appearing as included (or “reflected”) output unchanged within the response. The malicious input is said to be “reflected” back as part of the output code provided by the server to the client to be executed client-side. However, this same “input-output” mechanism exists client-side, albeit in a very different form, as we will outline below.
The flawed code is ultimately still written by in-house developers, but the difference is that the code is not executed (or any input evaluated) on the server-side; the flawed code is simply handed to the user’s browser as a static resource for it to evaluate and make use of, and the XSS occurs when a specific event fires within the page running in the client’s browser, using user-provided input.
Let’s suppose that the following code is used to create a form to let the user select their preferred language. A default language is also provided in the query string, as the parameter “default”.
Select your language: <select><script> document.write("<OPTION value=1>"+decodeURIComponent(document.location.href.substring(document.location.href.indexOf("default=")+8))+"</OPTION>"); document.write("<OPTION value=2>English</OPTION>"); </script></select>
The page is invoked with a URL such as:
A DOM Based XSS attack against this page can be accomplished by sending the following URL to a victim:
When the victim clicks on this link, the browser sends a request for:
Note that the HTTP response sent from the server does not contain the attacker’s payload. This payload manifests itself at the client-side script at runtime, when a flawed script accesses the DOM variable document.location and assumes it is not malicious.
The graph below shows global Google search volumes for the term ‘Single Page Application.’ Note the sharp rise in popularity from around 2011.
Preventing DOM XSS requires sensible precautions be taken during each step of the software development lifecycle (SDLC) to prevent a robust series of measures that together reduce the overall risk:
AppCheck help you with providing assurance in your entire organisation’s security footprint. AppCheck performs comprehensive checks for a massive range of web application vulnerabilities – including DOM XSS vulnerabilities and client-side code weaknesses – from first principle to detect vulnerabilities in in-house application code.
The AppCheck Vulnerability Analysis Engine provides detailed rationale behind each finding including a custom narrative to explain the detection methodology, verbose technical detail, and proof of concept evidence through safe exploitation.
AppCheck is a software security vendor based in the UK, offering a leading security scanning platform that automates the discovery of security flaws within organisations websites, applications, network, and cloud infrastructure. AppCheck are authorized by the Common Vulnerabilities and Exposures (CVE) Program as a CVE Numbering Authority (CNA).
As always, if you require any more information on this topic or want to see what unexpected vulnerabilities AppCheck can pick up in your website and applications then please get in contact with us: firstname.lastname@example.org
No software to download or install.
Contact us or call us 0113 887 8380