Cross Site
Scripting (XSS)
Web applications today suffer from different
vulnerabilities, but Cross Site scripting (XSS) is one of the most prevalent
web application security flaws and yet the most ignored one. It holds second
position in OWASP top 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
web site. 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 script in the victim’s browser and the malicious
script can access any cookies, session tokens, or other sensitive information
retained by our browser and 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 the social-networking sites like Twitter, Facebook, MySpace,
and Orkut.
An
example of a XSS Vulnerable Page:
The
following code segment in JSP (Java Server Pages) reads an employee ID: empid,
from a HTTP request and displays it.
<% String empid =
request.getParameter("empid"); %>
...
...
Employee ID: <%= empid %>
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 the XSS flaw found in the 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 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 than 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. It 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 vulnerability within a server side script, but an
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.
Some of the sample attack scenarios are as following:
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 one shown here:
<a href=http://VulnerableSite.com/registration.php?clprofile=<script>malicious
code here</script>>Click here</a>
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. Figure 1 shows the illustration of the
attack.
Figure 1. Attack via E-Mail
Session hijacking (cookie stealing)
Many web sites 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
session and gain sensitive information as shown in figure 2.
Figure 2. Cookie Stealing and Session Hijacking
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 a 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: http://ha.ckers.org/xss.html).
How it is different from CSRF (Cross
Site Request Forgery)
Most people often
confuse between 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 user to execute unwanted malicious
actions without their knowledge or intent on 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 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,
where another user, Max has posted a message. This message is a malicious link crafted
by Max, containing a HTML image element and refers an action on Bob’s bank
website.
<img src=http://Bobbank.com/withdraw?acc_name=bob&amount=1000&to=max>
Note here that there is no real image
file but if Bob’s authentication cookie (for bank website) hasn’t expired, then
as the Bob’s browser tries to load the image, it will automatically submit the
withdrawal form (along with the Bob’s cookie), thus an unintended transaction
from Bob’s account will take place.
Mitigating the flaw
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 for his/her safeguard against the 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.
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();
}
When a malicious
input in form of a script in inputted through the username field the vulnerable
page gives an alert popup, as displayed in figure
3. This could lead to session hijacking, client side defacement etc.
Figure 3: Popup occurs for a similar input
in Vulnerable Page
For
a similar input into the secure page, there is no effect of it, as the output
is encoded, as shown in figure 4.
Figure 4: No effect of malicious input on
Secure Page
Validating untrusted input
Input validation is
simply checking each input for validity. This can mean many things, but in the
simplest case, it means to check the type and length of the data. In this case
it can mean to check 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.
URL/UTF-7/Unicode/US-ASCII/etc. decode the incoming data.
·
Character-set checking
Ensure the data only contains expected characters.
Ensure the data only contains expected characters.
·
Length restrictions (min/max)
Ensure the data falls within a restricted minimum and maximum number of bytes.
Ensure the data falls within a restricted minimum and maximum number of bytes.
·
Data format
Ensure the structure of the data is consistent with what is expected.
Ensure the structure of the data is consistent with what is expected.
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. The modules and their
place in application architecture can be seen in figure 5.
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 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
- https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
- http://ha.ckers.org/xss.html
- http://www.steve.org.uk/Security/XSS/
- http://noscript.net/features
You can learn Ehtical Hacking from the Infosec Institute, one of the leading institute in the field of Information Security training: http://www.infosecinstitute.com/courses/ethical_hacking_training.html