Cross-site scripting (XSS) is a code injection security attack targeting web applications which delivers malicious, client-side scripts to a user’s web browser for execution. Targets are not attacked directly, rather vulnerable websites and web applications are used to carry out cross-site scripting attacks when users interact with these sites/applications.
When a web page is compromised with cross-site scripting, a collection of issues can quickly emerge. Possible concerns include, but are not limited to:
Cross-site scripting can be detrimental to an organization if it is not detected and handled in an immediate timeframe. With businesses and clients both at risk of XSS attacks, reputations and professional relationships can be negatively impacted following a successful malware injection.
An unfortunate example of cross-site scripting came during the 2018 Holiday Season with the rise of a credit card-skimming malware called ‘Magecart.’ The malware took advantage of a vulnerability by injecting itself into online check-out sites, and was the first time an attack of this nature occurred on such a large scale. User credit card information was likely uploaded to a server controlled by the attacker and potentially sold or used for fraudulent purchases.
Cross-site scripting attacks are typically categorized as one of the following types.
A reflected XSS attack involves a vulnerable website accepting data (i.e. malicious script) sent by the target’s own web browser to attack the target with. Because the malicious script is sent by the client itself and is not stored on the vulnerable server, this type of attack is also referred to as “non-persistent.”
A simple example of a reflected XSS attack could involve an attacker crafting up a URL that passes a small, malicious script as a query parameter to a website that has a search page vulnerable to XSS:
http://vulnerable-website.com/search?search_term=”<script>(bad things happen here)</script>”
The attacker then needs to have targets visit this URL from their web browsers. This could be accomplished by sending an email containing the URL (with plausible reason to trick the user into clicking it) or publishing the URL to a public, non-vulnerable website for targets to click.
When a target does click the link, the vulnerable site accepts the query parameter “search_term”, expecting that the value is something the target is interested in searching the vulnerable-website.com site for, when in reality the value is the malicious script. The search page then, as most website search pages will do when a user is searching for something, displays “Searching for <seach_term>...”, but because the vulnerable site didn’t sanitize the search_term value, the malicious script is injected into the webpage that the target’s browser is loading and is then executed by the target’s browser.
As the name implies, a persistent XSS attack is stored/persisted on the vulnerable server itself. Unlike a reflected attack, where the malicious script is sent by the target, users of a vulnerable website or web app can be attacked during their usual interactions with the vulnerable site/app.
A simple example of a persistent XSS attack could involve an attacker posting a message to a forum hosted on a vulnerable website. Rather than a usual, innocuous forum post, this post content contains the attacker’s malicious script. When a user visits this forum post, their web browser loads and executes the malicious script.
As you can see, a key differentiator between reflected and persistent XSS attacks is that persistent XSS attacks consider all users of a vulnerable site/app as targets for attack.
Another type of XSS attack is DOM-based, where the vulnerability exists in the client-side scripts that the site/app always provides to visitors. This attack differs from reflected and persistent XSS attacks in that the site/app doesn’t directly serve up the malicious script to the target’s browser. In a DOM-based XSS attack, the site/app has vulnerable client-side scripts which deliver the malicious script to the target’s browser. Similar to a reflected attack, a DOM-based attack does not store the malicious script on the vulnerable server itself.
A simple example of a DOM-based XSS attack could involve the same setup for the reflected XSS example scenario above. The attacker creates a URL with a malicious script as the “search_term” and solicits it to potential targets. Once a target clicks the URL, their browser loads the site search page and the vulnerable client-side processing scripts. While the “seach_term” is still provided as a query parameter to the site back end for processing, the site itself does not generate the web page with the injected malicious script. Instead, the site’s vulnerable client-side scripts are designed to locally (in the target’s browser) dynamically substitute in the search term value (i.e. the malicious script) in the target’s rendered search page, causing the target’s browser to load and execute the attacker’s script.
DOM-based XSS attacks highlight the fact that XSS vulnerabilities aren’t limited to server-side software.
With multiple variations of cross-site scripting attacks, organizations need to know how to adequately protect themselves and prevent future problems. Websites are starting to become harder to strictly monitor than ever before due to how complex they are becoming. The frequency of attacks will likely continue to rise as time goes on.
The following suggestions can help safeguard your users against XSS attacks:
Sanitize user input:
Limit use of user-provided data:
Utilize the Content Security Policy:
Regularly use a web application vulnerability scanning tool to identify XSS vulnerabilities in your software.
While XSS attacks continue to be a popular (and successful) vector of attack, a bit of thoughtful design and testing can go a long way in keeping your website or web application from being vulnerable (and keeping your users protected). Learn more about web application security testing.