Cross-Site Scripting (XSS) vulnerabilities can, unfortunately, be found in all types of web-based applications. Indeed, they appear to be rather ubiquitous across the web. XSS falls into the category of code injection vulnerabilities and is a result of web-based applications consuming user-supplied input without proper filtering and sanitization. Although XSS attacks exist due to web application defects such as implementation flaws, successful exploitation of XSS vulnerabilities actually targets (in most cases) the end users of the web application's service instead of the service itself. For example, a successful XSS exploitation can allow script to execute within a victim's browser (i.e., the web application's end user). However, XSS can be used in an attack chain sequence, coupled with other web application vulnerabilities such as Cross-Site Request Forgery (CSRF), to eventually penetrate the web application and/or its server. To learn more about the differences between CSRF and XSS and how they can be coupled into an attack, please refer to Craig Young's blog post. In 2011, XSS ranked 4th in the “2011 CWE/SANS Top 25 Most Dangerous Software Errors” list and it is listed third in the OWASP Top 10 for 2013 Web Application Security risks. The Common Weakness Enumeration (CWE) dictionary gives XSS a Weakness ID of 79 and is titled “CWE-79: Improper Neutralization of Input During Web Page Generation”. From the 2011 CWE/SANS Top 25 report, XSS is described as follows:
“Cross-site scripting (XSS) is one of the most prevalent, obstinate, and dangerous vulnerabilities in web applications. It's pretty much inevitable when you combine the stateless nature of HTTP, the mixture of data and script in HTML, lots of data passing between web sites, diverse encoding schemes, and feature-rich web browsers. If you're not careful, attackers can inject Javascript or other browser-executable content into a web page that your application generates. Your web page is then accessed by other users, whose browsers execute that malicious script as if it came from you (because, after all, it *did* come from you). Suddenly, your web site is serving code that you didn't write. The attacker can use a variety of techniques to get the input directly into your server, or use an unwitting victim as the middle man in a technical version of the "why do you keep hitting yourself?" game.”
In this blog post, I will compare two Cross-site Scripting (XSS) vulnerabilities that I have previously discussed, namely, CVE-2014-1879 and CVE-2014-3988. CVE-2014-1879 is a reflected (aka non-persistent) XSS vulnerability in phpMyAdmin, and CVE-2014-3988 is a persistent (aka stored) XSS vulnerability in KCFinder. Before proceeding with the comparison, let’s first review the difference between reflected and persistent XSS vulnerabilities. Reflected XSS is a non-persistent XSS vulnerability where injected script is executed immediately. To exploit reflected XSS vulnerabilities, it is common for script to be injected into a vulnerable web application via constructs such as HTTP query parameters or HTML forms. Note that successful exploitation of most reflected XSS vulnerabilities will only result in execution of its associated injected script once. However, persistent XSS vulnerabilities behave differently. Script injected into a persistent XSS vulnerability is stored, usually within a vulnerable web application’s database. As a result, successful exploitation of a persistent XSS vulnerability can result in multiple executions of its injected scripts, potentially targeting large numbers of different users. CVE-2014-1879 and CVE-2014-3988 are similar in terms of how script can be injected into their associated applications. Both of these vulnerabilities can be exploited by adding script to the names of files used by the applications. In particular, these vulnerabilities exist because their associated web applications do not properly sanitize file names that are processed by the web applications. As a result, malicious actors can embed JavaScript (or script from other browser-friendly languages) into the name of a file that is either stored on the web app’s server or uploaded from a client. Successful exploitation of these vulnerabilities can do a number of operations ranging from executing a simple and benign popup to more mischievous actions such as stealing a user’s browser cookies. Let’s look at CVE-2014-1879 a little closer. CVE-2014-1879 is a reflected XSS vulnerability that exists within the phpMyAdmin file import interface. The vulnerability is exploitable by adding script to the name of a file added to phpMyAdmin through its file import interface. To exploit this vulnerability, an authenticated user needs to login to the phpMyAdmin interface, create a file with script embedded into the file’s name, and then upload the file via the phpMyAdmin import interface. Once the malicious file is uploaded, the import interface will process the file name and render a page that results in execution of the embedded script. However, execution of the script occurs within the browser and context of the user who uploads the malicious file. At first, this might sound like a moot issue, but let’s consider this a bit further. CVE-2014-1879 is a reflected XSS vulnerability where an authenticated user of a vulnerable phpMyAdmin instance would need to upload a file containing script embedded within the file’s name. The resulting exploitation actually targets the user who uploads the malicious file. Who would ever do such a thing? After all, why would a user want to hack himself? Well, this is a situation where social engineering could play a role. Specifically, a successful attack on CVE-2014-1879 would utilize social engineering. For example, a user of a vulnerable phpMyAdmin instance would need to be duped into uploading a malicious file supplied by an attacker. Since so much work is required to achieve a fruitful exploitation of CVE-2014-1879, it can be categorized as a vulnerability with relatively low security impact and risk. However, the same cannot be said for CVE-2014-3988. So, let’s look at CVE-2014-3988 a little closer. CVE-2014-3988 is a persistent XSS vulnerability. For this vulnerability, a user who has access to a server running KCFinder with read and write access to the file system (via the web application) can create files or folders on the server with names that contain embedded script. Often times, one might consider a XSS vulnerability to be persistent if the injected code is stored within the web application’s database. With CVE-2014-3988, the script is stored on disk as a file (or folder) name. A malicious user who has access to a KCFinder instance with permissions to write to disk via the web application can exploit this vulnerability. Then, when other users of the system browse to the location of the malicious file, the script will execute within the context of their browsers. Consequently, this vulnerability can be more harmful than CVE-2014-1879 because social engineering tactics are not necessarily required to achieve exploitation. Moreover, KCFinder is often used as a “plugin” to extend the functionality of other web applications. So, any application that includes the unpatched version of KCFinder will be vulnerable by extension. XSS vulnerabilities can be found all over the web. Hopefully, this article will help you to understand them and their associated consequences just a little bit better. Stay tuned—in my next blog post, I will talk about XSS vulnerabilities and how the emerging “Internet of Things” will be impacted by them.