Cross Site Scripting (originally CSS but the acronym was changed to XSS to avoid confusion with Cascading Style Sheets), also known as an arbitrary script injection flaw, is a pernicious vulnerability in web applications. Noted in the OWASP Top 10 most common web application vulnerabilities XSS is an often misunderstood and overlooked. XSS can allow an attacker to take control of a victim web browser, often without leaving any trace of their attack. XSS targets web application users rather than the application server, as is the case in attacks leveraging SQL injection, authentication bypass, or code execution vulnerabilities. Because XSS vulnerabilities affect site users, rather than application infrastructure, it is often overlooked by developers or security officers. However, as the browser becomes closer to a complete operating system for many users it is becoming an increasingly attractive target, and platform, for attack.
Causes of XSS
XSS is caused by the fact that HTML encodes data and instructions in the same format (plain text). When HTML transmission occurs (over HTTP) the body of the communication contains the content of the HTTP message encoded in HTML. As anyone who has tried to write HTML knows, the only difference between instructions to browsers concerning the layout and appearance of a page and the text to present on the page are less-than (<) and greater-than (>) symbols that delineate tags. Tags are HTML elements surrounded by these less than and greater than symbols in the same way that XML delineates content. Thus, the characters that segregate data from instructions are used as character of data for display as well. Confusion over delineation is further exacerbated by the fact that tags can have attributes, delimited by quotes (single or double, or in some cases no quotes) and spaces, which are also displayed characters.
The complexity of segregating instructions to the client browser from content being displayed makes for a fertile attack surface. XSS is a vulnerability that allows an attacker to exploit this confusion, escape the bounds of delineation (much like in SQL Injection attacks) and hijack either data or instructions given to the browser. This enables arbitrary script injection into a web page.
In order to carry out an exploit attackers craft malicious pieces of user supplied data to inject attack code. This injection can take two main forms: a transient attack where the malicious content is carried within the request (such as within a link), called reflected XSS, and persistent XSS where malicious data is injected into an applications permanent data store (such as a back end database). Whenever an application displays user supplied input, of any form, from web form post data to url data to previously supplied data like profile information, or even the filenames of uploaded pictures, the potential for XSS attack exists.
Threats from XSS
Many security researchers consider XSS a "lame" exploit. It is much derided in the popular information security press. Part of this perception stems from the sheer volume of XSS vulnerabilities. An entire website, xssed.com, exists to highlight publicly disclosed cases of XSS vulnerabilities. ComputerWeekly recently published an article showing XSS as the top threat to web applications (http://www.computerweekly.com/news/2240168930/XSS-attacks-remain-topthreat- to-web-applications). As aforementioned, OWASP considers XSS one of the top threats facing web applications as well (https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)).
It doesn't take much skill to find XSS vulnerabilities in applications simply because they are so common. This fact combines with the fact that due to the deductive reasoning required to identify XSS in applications, automated tools cannot identify any but the simplest of XSS flaws. This means that running an application security scanner against a web application will more than likely to reveal only a small portion of XSS flaws. Examining any major vulnerability announcement list will show such a volume of XSS vulnerabilities that many vendors simply don't publish them. Bug bounty programs often refuse to pay for such flaws simply because they are so common. Despite the derision, however, XSS vulnerabilities present a serious threat to most organizations.
Real World XSS
To demonstrate the seriousness of an XSS vulnerability I would like to propose the following, very real, scenario. Using XSS it becomes trivial to harvest user credentials. The reason for the simplicity of this attack is that with XSS an attacker can leverage a user's trust in both their web browser, and the application source. The fact is that an XSS attack can fundamentally change the behavior of a web application, without changing any visual queues to a user such as the URL bar, the green SSL padlock, or other security countermeasures. Because the XSS attack is operating under the context of the targeted web application, with the full privileges of the web browser, it is nearly impossible for a victim to spot the attack. Additionally, because a careful XSS attack issues legitimate instructions to the web browser, the malicious content is technically indistinguishable from legitimate content. This means that anti-malware software cannot detect an XSS attack.
A far more insidious XSS attack would not attempt to make any unauthorized changes to a users system. Because XSS is invisible to an end user it is possible to use XSS to socially engineer (trick) a user into supplying valid credentials for accounts or even to download and install malware voluntarily. XSS allows an attacker to take the place of trusted sources, even if only for a short time, and leverage that trust to attack users without their knowledge.
Consider, for a moment, a typical organizational environment of reasonable size. Think of an organization with a few web applications that support business process. Usually such organizations implement some sort of Single Sign On (SSO) infrastructure like Kerberos, OpenID, Integrated Windows Authentication, CoSign or even Facebook or Google authentication. Whenever an authorized party interacts with one of the web applications they are presented with an authentication form. Once completed this form is submitted and the client is authorized for all the applications without having to re-authenticate. This type of authentication and authorization is convenient because it is simple. It is dangerous because one set of credentials will typically allow access to a mixed range of security sensitive resources (for instance the same credentials might give access to the organizational calendar as well as the employee retirement allocation application).
The SSO model is easy for employees who only have to remember a single set of credentials. However, it has the side effect of habituating users to the presentation of a standard login form. Often times, due to credential expiration, the login form may appear in the middle of a workflow. A user may authenticate, use an application, step away for a while, return to the application and click on an internal link only to be presented with the login form. Thus the authentication process doesn't always happen at the "front door" of the application, with a single workflow that starts with authentication, but may present itself once the user is already using the application if the authenticated session has a time expiry.
This landscape is a gold mine for attackers. If an attacker can find an XSS flaw in an application, not necessarily even one behind authentication, they can use the XSS to present the authentication screen to a user. It is easy for an attacker to find and copy the authentication screen because it is uniform and the attacker merely needs to find a link to a resource that requires authentication to discover its format. The attacker then scrapes the page and injects it using an XSS attack. Victims will encounter a page, at a valid organizational URL, that suddenly presents them with the login screen. Victims are habituated to being presented with the login screen unprompted and will fill out the form, which can silently post the results back to an attacker. This attack could even defeat two factor authentication if the second factor is valid for a time window and the attacker can harvest and re-use the credentials in time. The only indication to a victim is the URL, which will differ from the correct SSO URL but will not be invalid.
Implementing a Harvesting Attack
While the description of this attack may seem interesting to all but technical users who can instantly visualize an attack, this article will now enumerate exactly how a real attack could take place in order to demonstrate the ease of the attack and the magnitude of the impact. I won't use any real organizations in this demonstration, but applying this model is trivial.
var newdiv = document.createElement('div'); newdiv.style.width = "100%"; newdiv.style.height = "100%"; newdiv.style.position = "absolute"; newdiv.style.left = 0; newdiv.style.top = 0; document.body.appendChild(newdiv);
newdiv.innerHTML = 'Any arbitrary HTML code';
The following screenshot shows a typical login screen that a user might encounter in a Drupal web application if their session timed out or the first time they encountered restricted content (for instance by clicking on a bookmark to the administrative secion of the site):
Fig 1: Example access denied (supply credentials) screen
Next is a demonstration of a typical content page. Note the URL is valid and complete, and although this example is not served over HTTPS it could well be, and include a valid lock.
Fig 2: Example webpage as it would normally appear
This web page contains a trivial XSS vulnerability. A traditional proof of concept would cause an alert box to appear. Note the URL is still valid and unchanged.
Fig 3: Trivial XSS demonstration with an alert box
Fig 4: A credential harvesting XSS attack is undetectable
XSS flaws are some of the most common flaws in web applications today. Unfortunately, due to the complexity of web applications and the need for customized filtering rules when sanitizing user supplied input, it is extremely difficult for automated tools to identify any but the simplest XSS vulnerabilities. Sadly, it is quite easy for a human to deductively reason through defensive filters that are applied to user supplied data. This means that while automated scanners are not very good at finding XSS vulnerabilities, human adversaries are quite adept at finding these flaws. The resulting situation is that XSS flaws abound, they are difficult for defenders to detect, involve complex technical fixes, and are easy for adversaries to exploit. This provides a fertile ground for attack.
Real world XSS attacks often involve client side exploits using third party plugins. These technical attacks are easily addressed using technical solutions such as update browsers and plugins and anti-virus software. Non technical attacks are set to become more common as attackers realize their effectiveness. The growth of online applications is dramatically increasing the value of application credentials. The convenience and proliferation of single sign on mechanisms is broadening the usefulness of a single set of credentials. Thus, the returned value of compromised credentials is rising. The fact that technical controls cannot easily prevent social engineering attacks, combined with the proliferation of XSS flaws and the potential for these flaws to be used for extremely successful social engineering attacks creates a house of cards waiting to fall.
Although SQL injection has dominated the news recently, it is only a matter of time before XSS replaces SQLi as the top threat occupying the media, and attackers. While SQLi is quite easy to find in source code, and remedy through a broad array of technical solutions from prepared statements to SQL filtering proxies, no such equivalent exists for XSS vulnerabilities. This fact, combined with evolving attack tools, and the broad impact of XSS as well as the pervasiveness of SSO means that at some point in the very near future XSS will become the dominant threat facing the web application ecosystem.