Cross-Site Scripting (XSS) Vulnerabilities
XSS: The most commonly exploited vulnerability
Cross-site scripting (XSS) is one of the most common and well-known vulnerabilities contained within web applications. It consistently appears in the OWASP list of the Top Web Application Security Risks and was used in 40% of online cyberattacks against large enterprises in Europe and North America in 2019. According to HackerOne, XSS vulnerabilities are the most common vulnerability type discovered in bug bounty programs, despite the fact that most companies undervalue it because it rarely leads to large-scale data breaches.
The root cause of XSS vulnerabilities is when a web application uses untrusted input without performing proper validation first. If a web server embeds user input in a page’s HTML code before sending it to the client, then malicious input could enable the execution of attacker-controlled code within the user’s browser.
This becomes a serious security problem due to the same-origin policy used to control access to data within web pages. Anything coming from the same place has access to the same set of data. This means that an attacker’s script embedded within a legitimate page processing sensitive information (credit card numbers, etc.) will have access to that information as well and is able to send a copy to the script’s operator.
Types of XSS exploits
XSS attacks all take advantage of insecure use of untrusted user input within a web page. However, there are a few different ways in which an attacker can perform an XSS attack.
Document object model (DOM)-based XSS
DOM-based XSS occurs completely within the user’s browser. While it exploits a vulnerable web page and an attacker-generated malicious script is sent to the server, the server’s response does not include the malicious string. Instead, the server sends back a script that is executed within the user’s browser and uses untrusted input to modify the HTML code of the displayed page.
An example of a DOM-based XSS attack is one that takes advantage of search functionality on a web page. The attacker initiates the attack by sending a user a URL that contains a search for a malicious string. A request to the server for the target URL results in a legitimate script for searching a page for a given string. When the user’s browser executes this script, it embeds the malicious string within the webpage by saying something like “You searched for <malicious string>”. As a result, the attacker-provided script contained within the malicious string is executed, exploiting the user’s browser.
Reflected XSS exploits take advantage of web pages that embed user-provided input within a web page. For example, a page may be designed to greet a user by name if that name is included in the URL as an HTTP query.
With reflected XSS, an attacker gets the target to follow a malicious link. In this link, the user input that will be embedded in the target page contains a script exploiting the XSS vulnerability. When the user visits the page, the attacker-provided script is executed within their browser.
Stored XSS attacks add persistence to an XSS attack. Instead of directly targeting a particular user, stored XSS enables exploitation of every visitor to a particular web page.
This is accomplished by making the XSS exploit a permanent part of a web page. This can be accomplished in a number of different ways. An attacker might take advantage of a page’s support for comments, reviews, forum posts and so on that keeps user-provided input on-page. Alternatively, an attacker may gain access to a webserver and modify HTML code directly. Regardless of the technique, stored XSS does not require a user to click on a malicious link and impacts all visitors to the exploited web page.
Mitigating XSS vulnerabilities
An application may be vulnerable to XSS exploitation if it uses untrusted user input to update the HTML of a web page. If done so incorrectly, malicious user input can be interpreted as part of the page’s legitimate code and executed (if it is a script).
XSS vulnerabilities can be mitigated in a couple of different ways. One is to ensure that user input doesn’t contain anything malicious or potentially damaging. Performing input validation to remove <script> tags and similar suspicious content before adding user input to a page can decrease the probability of exploitation.
A more generally effective technique is to escape any user input before adding it to a web page’s code. Escaped input will not be considered code by the user’s browser — making it impossible for scripts included in this input to run — but will be unescaped and properly rendered by the browser at the other end. This eliminates the threat of XSS with no impact on the legitimate contents or functionality of the web page.