Cross-Site Scripting (XSS)
Web applications today suffer from a variety of vulnerabilities. Cross-Site Scripting (XSS) is one of the most prevalent web application security flaws, yet possibly the most overlooked. It holds the second position in the OWASP Top Ten 10 Web Application Security Risks for 2010.
Cross-Site Scripting is a type of injection problem in which malicious scripts (vb, js etc.) are injected into a trusted website. XSS flaws occur whenever an application takes untrusted (typically user-supplied) data and sends it invalidated or unencoded to a web browser. XSS allows attackers to execute scripts in the victim's browser and the malicious script can access any cookies, session tokens, or other sensitive information retained by our browser. Used with that site, they can even rewrite the content of the HTML page. It basically exploits the trust that a client browser has for the website. In XSS the user trusts that the content being displayed in their browser was intended by the website to be displayed. Cross-site scripting carried out on websites accounted for roughly 80% of all security vulnerabilities documented by Symantec as of 2007. Prominent sites affected in the past include social networking sites like Twitter, Facebook, MySpace, and Orkut.
11 courses, 8+ hours of training
11 courses, 8+ hours of training
An example of an XSS Vulnerable Page:
The following code segment in JSP (Java Server Pages) reads an employee ID: empid, from an HTTP request and displays it.
[sourcecode]
<% String empid = request.getParameter("empid"); %>
...
...
Employee ID:
[/sourcecode]
The above code operates correctly if empid contains only standard alphanumeric text, but if empid has a value that includes script (js, vb etc.) or meta-characters, then the code (maybe malicious) will be executed by the web browser.
Types of XSS:
There are basically three types of XSS flaws: reflected, stored and DOM-based.
Reflected or Non-persistent:
The reflected cross-site scripting is the most common type of XSS flaw found in web applications today. In this kind of flaw, the injected code is reflected off the web server, such as in a search result, an error message, or any other response that includes complete or partial input sent to the server as part of the request.
The attacker needs to deliver the attack to the victims via another route, such as in an e-mail message, or on some other web server. The attacker sends the malicious link to the victim and when the victim is tricked into clicking on a malicious link or submitting a specially crafted form (through Social Engineering etc.), the injected code travels to the vulnerable web application's server, which reflects the attack back to the victim's browser. The browser then executes the malicious code as it came from a "trusted" server.
Stored or Persistent:
The stored XSS vulnerability is a more devastating variant of a cross-site scripting flaw. In a Stored kind of flaw, the attacker can inject malicious code into the vulnerable application and the injected code is permanently stored on the target servers (in a db, comment field, visitor log, etc.) and then permanently displayed on "normal" pages returned to other users in the course of regular browsing. Persistent XSS is quite significant as compared to other types as an attacker's malicious script is rendered automatically, without the need to individually target victims or lure them to a third-party website. This is a dangerous flaw as any data received by the vulnerable web application (via email, system logs, etc.) that can be controlled by an attacker could become an injection vector. A classic example would be an attacker leaving a malicious script on a blog's comment field of a vulnerable blogging web application. The malicious script will execute in the browsers of the users who will visit the blog later.
DOM-based:
DOM is a World Wide Web Consortium (W3C) specification, which defines the object model for representing XML and HTML structures. DOM Based XSS or type-0 XSS is an XSS flaw wherein the attack payload is executed as a result of modifying the DOM "environment" in the victim's browser used by the original client-side script so that the client-side code runs in an "unexpected" manner. DOM-based XSS is not a result of a vulnerability within a server-side script, but improper handling of user-supplied data in the client-side JavaScript. Like the other types of XSS vulnerabilities, DOM-based XSS can be used to steal confidential information or hijack the user account. However, it is essential to understand that this type of vulnerability solely relies upon JavaScript and insecure use of dynamically obtained data from the DOM structure.
Attack scenarios
Some of the sample attack scenarios are as follows:
Scripting via a malicious link
In such a scenario, the attacker sends a crafted e-mail message to a victim containing a link (containing malicious script) such as the one shown here:
[sourcecode wraplines="true"]<a href="http://VulnerableSite.com/registration.php?clprofile=<script"> malicious code here>Click here</a>
[/sourcecode]
When an unsuspecting user clicks on this link, the URL is sent to VulnerableSite.com including the malicious code. As the legitimate server sends a page back to the user including the value of clprofile (Client's profile), the malicious code will be executed on the client's web browser.
Session hijacking (cookie stealing)
Many websites use cookie-based user authentication and rely solely on session cookies for authentication between individual HTTP requests, and because client-side scripts generally have access to these cookies, simple XSS exploits can steal these cookies. In such a scenario, the attacker may send a malicious link or store a malicious script on a page (stored XSS) of the vulnerable site. When the malicious page is displayed, the malicious script executes, collects the user's cookies, and sends a request to the attacker's Web site with the cookies gathered. Using this technique, the attacker can hijack user sessions and gain sensitive information.
How to detect if a website is vulnerable?
Cross-site scripting flaws can be difficult to identify and remove from a web application. The best practice to search for flaws is to perform an intense code review and search for all places where user input through an HTTP request could possibly make its way into the HTML output. A variety of different HTML tags (such as <img src…>, <iframe…>, <bgsound src…> etc.) can be used to transmit a malicious JavaScript. WebScanner tools like Burp Suite, WebInspect, Acunetix, Netsparker, Websecurify, NStalker etc. can be used to hunt for such web vulnerabilities, but along with manual testing as most of the tools only test using common scripts and ignore different encodings and bypassing techniques (described by RSnake).
How it is different from CSRF (Cross-Site Request Forgery)
Most people often confuse XSS and CSRF. Both vulnerabilities require different methods of exploiting and securing web applications. Cross-site request forgery or session riding is a kind of attack which forces end users to execute unwanted malicious actions without their knowledge or intent on the web application in which they are currently authenticated. Cross-site Scripting is the ability to make a website display user-supplied content embedded with HTML/JavaScript. CSRF exploits the trust a website has for the user's browser unlike XSS, which takes advantage of the trust a client browser has for the website. In CSRF the website trusts that the request coming from the user's browser is intended by him, whereas in XSS the user trusts that the content being displayed in their browser was intended by the website to be displayed.
An example of a CSRF attack:
One user, Bob is browsing a forum, whereas another user, Max has posted a message. This message is a malicious link crafted by Max, containing an HTML image element and refers to an action on Bob's bank website.
[sourcecode]
<img src="http://Bobbank.com/withdraw?acc_name=bob&amount=1000&to=max" />
[/sourcecode]
Note here that there is no real image file but if Bob's authentication cookie (for bank website) hasn't expired, then as Bob's browser tries to load the image, it will automatically submit the withdrawal form (along with Bob's cookie), thus an unintended transaction from Bob's account will take place.
Mitigating the flaw
The following techniques can be used to safeguard against this vulnerability
User End: A user can take the following measure to secure himself/herself from XSS
Disabling scripts
Although Web 2.0 and Ajax designers favor the use of JavaScript, some web applications are written to (optionally) operate completely without the need for client-side scripts. This allows users, to disable scripting in their browsers before using the application. In this way, users would not be susceptible to XSS attacks even if potentially malicious client-side scripts are inserted without encoding on a page.
Some browsers or browser plugins can be configured to disable client-side scripts on a per-domain basis. One such solution for Firefox and other Gecko-based browsers is the open-source NoScript add-on which, in addition to its ability to disable scripts on a per-domain basis, also provides some anti-XSS protection even when scripts are enabled, but it could also decrease the functionality of the website. This technique can be used by the user to his/her safeguard against vulnerability.
Developer End: Following techniques can be used by developers to make the web application free from XSS
Output encoding
The primary defense mechanism to stop XSS is contextual output encoding or escaping. "Escaping" is a technique used to ensure that characters are treated as data, not as characters that are relevant to the interpreter's parser. It is the primary means to make sure that untrusted data can't be used to convey an injection attack. There is no harm in escaping data properly - it will still render in the browser properly. Escaping simply lets the interpreter know that the data is not intended to be executed, and therefore prevents attacks from working. An example code in JSP for escaping is shown below.
[sourcecode]
public static String encode(String data)
{
final StringBuffer newbuf = new StringBuffer();
final char[] chars = data.toCharArray();
for (int i = 0; i < chars.length; i++)
{
newbuf.append("&#").append((int) chars[i]);
}
return newbuf.toString();
}
[/sourcecode]
When a malicious input in form of a script in inputted through the username field the vulnerable page gives an alert popup. This could lead to session hijacking, client-side defacement etc.
Validating untrusted input
Input validation is simply checking each input for validity. This can mean many things, but in the simplest case, it means checking the type and length of the data. In this case, it can mean checking for common scripted inputs, their variations and encoded forms. If input validation is done properly throughout the website code we would wipe out a large number of vulnerabilities like XSS and SQL Injection etc. Input validation should be performed on any incoming data that is not controlled and trusted. This includes user-supplied data, data from a third party, or elsewhere.
Before using any untrusted incoming data following steps need to be followed:
- Normalize
URL/UTF-7/Unicode/US-ASCII/etc. decode the incoming data.
- Character-set checking
Ensure the data only contains expected characters.
- Length restrictions (min/max)
Ensure the data falls within a restricted minimum and a maximum number of bytes.
- Data format
Ensure the structure of the data is consistent with what is expected.
(Source: Jeremiah Grossman)
Implementing WAFs
Firewalls have been extensively used to safeguard servers by implementing network-based rules; similarly, a web application firewall (WAF) is an appliance, server plugin, or filter that applies a set of rules to an HTTP conversation. Generally, these rules cover common attacks such as Cross-site Scripting (XSS) and SQL Injection. By customizing the rules to the application, many attacks can be identified and blocked. The effort to perform this customization can be significant and needs to be maintained as the application is modified. Some common examples of WAF are ModSecurity and PHPIDS.
Security API
ESAPI (The OWASP Enterprise Security API) is a free, open-source, web application security control library developed by OWASP, that makes it easier for programmers to write lower-risk applications. The ESAPI libraries are designed to make it easier for programmers to retrofit security into existing applications. The ESAPI libraries also serve as a solid foundation for new development.
Conclusion
With the advent of Web 2.0, Web Applications have significantly improved in functionality as well as presentation but at the same time the risk factor has also increased. The ignorant implementation of these technologies impacts the functionality as well as the behavior of the application which poses a significant risk for the end user. The risk becomes even graver when another flaw in a component is fused with it (in this case XSS + CSRF). Thus, in order to be secure, the developers as well as the end users should take due precautions when dealing with web applications.
References for further reading