The Anatomy of Cross Site Scripting
LogError writes "Many documents discuss the actual insertion of HTML into a vulnerable script, but stop short of explaining the full ramifications of what can be done with a successful XSS attack. While this is adequate for prevention, the exact impact of cross site scripting attacks has not been fully appreciated. This paper will explore those possibilities."
The Anatomy of Cross Site Scripting
Anatomy, Discovery, Attack, Exploitation
by Gavin Zuchlinski (gav@libox.net )
http://libox.net/
November 5, 2003
Introduction
Cross site scripting (XSS) flaws are a relatively common issue in web
application security, but they are still extremely lethal. They are
unique in that, rather than attacking a server directly, they use a
vulnerable server as a vector to attack a client. This can lead to
extreme difficulty in tracing attackers, especially when requests are
not fully logged (such as POST requests). Many documents discuss the
actual insertion of HTML into a vulnerable script, but stop short of
explaining the full ramifications of what can be done with a successful
XSS attack. While this is adequate for prevention, the exact impact of
cross site scripting attacks has not been fully appreciated. This paper
will explore those possibilities.
Anatomy of a Cross Site Scripting Attack
A cross site scripting attack is typically done with a specially crafted
URI that an attacker provides to their victim. The XSS attack could be
considered analogous to a buffer overflow, where the injected script is
similar to overwriting an EIP. In both techniques, there are two options
once a successful attack has occurred: insert funny data or jump to
another location. Insertion of funny data during a buffer overflow
typically results in a denial of service attack. In the case of a XSS
attack, it allows the attacker to display arbitrary information, and
suppress the display of the original webpage. When jumping to
another location during a buffer overflow attack, the new location is
another location in memory where shellcode or other important data
resides - allowing the attacker to take control of the flow of the
program. Within the XSS context, the attacker instead jumps the
victim to another location on the Internet (typically under the
attacker's control), hijacking the victim's web browsing session.
Discovery
But how do cross site scripting attacks occur? XSS attacks are the
result of flaws in server- side web applications and are rooted in user
input which is not properly sanitized for HTML characters. If the
attacker can insert arbitrary HTML then they could control execution of
the page under permissions of the site. A simple page vulnerable to
cross site scripting looks like:
Once the page is accessed, the variable sent via the GET method is
placed directly on the rendered page. Since the input is not marked as
variable input , the user- supplied input is interpreted exactly as its
metacharacters command, very similar to SQL injection. Passing
"Gavin Zuchlinski" as an argument outputs the content in correct form:
Sending input with HTML metacharacters allows for unexpected output:
The input is not validated by the script before rendering by the victim's
web browser. This allows for user controlled HTML to be inserted on to
the vulnerable page. Occasionally user input not directly parsed by the
script it is sent to. Rather, the data is inserted into a file or database
and retrieved later to be reinserted on the page.
Common points where cross site scripting exists are confirmation
pages (such as search engines which echo back user input in the event
of a search) and error pages that help the user by filling in parts of the
form which were correct. Commonly in the latter case (and sometimes
the former) the containment of the form text box must be escaped
with a quote and a greater than sign ("> - the quote closes the value
property and the greater than closes the tag).
Attack
Once a vulnerable input is identified the valid HTTP methods must be
determined. The way in which the variables are sent to the target
script is an important consideration; are variables sent by GET, POST,
or will either work? Some scripts are specific, but several which use
canned methods (like PHP and Perl scr
Why is Cross Site Scripting XSS? Or have we reverted to referring to letters by the way they look?
Cross Site Scripting attack protection is a standard feature of many network security products these days. Check Point NG with Application Intelligence (Feature Pack 4 in other words) includes XSS protection as part of its' so-called SmartDefense. I am curious if anyone has run into situations where SmartDefense is screwing up legitimate traffic, especially traffic that resembles an XSS attack.
BTW, does anybody have some good recommendations for cheaper alternatives with pretty comparable protection to Check Point? I would like something that is as defensive, but not as configurable or extensible.
In principio erat Verbum.
I'm surprised this merited a news item.
Webmonkey had a similar article three and a half years ago, that provide some more solid examples of what happens.
I designed an e-commerce site over the last six years, and evaluated where there might be XSS vulnerabilities. Not having a bulletin board or guestbook removes many areas for exploitation.
So if someone types contaminated data into their address field when checking out, you'd think all it hoses is their own purchase, right?
Well, with PHP or Perl CGI, it's possible that the inputted variables could exploit server knowledge: if you know the variable names used in the PHP code for, say, the MySQL password, then embedding this in the input to be evaluated on output can open an avenue for hacking. The variable has to be evaluated in most cases, although code which generates new PHP pages could result in similar problems.
HTML encode EVERYTHING the user sends to you.
Design for Use, not Construction!
Although it is PHP-specific, this free article explains XSS and CSRF in quite a bit of detail and might be useful for Web developers using any language:
http://www.phparch.com/sample.php?mid=16
Enjoy
Just because a password is MD5-encoded doesn't mean it's useless.
1) You can put the user ID and MD5-encoded password in your own cookies, and log in as the user.
2) You can find another site that user logs in on, find their user ID, and use the captured MD5 password to log in as them -- people tend to use the same password in many places
3) You can feed the MD5 password into a password cracker. If it's in a dictionary, you'll get the cleartext version in seconds; brute-forcing all possible 7-character passwords only takes a few weeks.
"They redundantly repeated themselves over and over again incessantly without end ad infinitum" -- ibid.
*cough*
Its this kind of lack of understanding that makes the problem so prevelant.
First it doesn't make sense to htmlencode everything just as id doesn't make sense to addslashes everything (now turned off by default in all good php configurations).
Here's why: Not everything that comes in is to be displayed as html, just as not everything that comes in is destined for the database.
Unless you understand the risks, you can't guard against them though it appears some people are still able to be certain they have guarded against them.
If you do this,
sqlquery("select * from user where username='$user'") then you need to think what the problem is, its a well defined problem, it is that $user may contain a final ' mark and then some; maybe:
$user="jimjoe' or 1'"
so your preferences page now shows the first user in the db, or depending on your web page, all of them.
In php, htmlentities doesn't encode the '
If you are invoking system commands (and yes I one had to do a LOT of this from php) then be careful about shell meta characters like ` ' " and $ in certain cases.
The principle is that you need to make sure the system you are passing data on to interprets it in the literal sense that you require and you cannot do this unless you understand completely how each of the systems you will pass the data on to really does interpret data.
So if your user data is destined for the database, then escape it, something like:
sqlquery(sprintf("select * from user where username='%s'",addslashes($user)));
(yes there are other better was of doing it)
If you want to display on the web page inline:
echo htmlentities($user);
on the other hand if you want to display in an text area I think there is other encoding to use. If it is for a url you need to urlencode and htmlentities but I forget the order.
Understand the system you are communicating with.
Sam
blog.sam.liddicott.com
http://cgisecurity.com/lib/xss_anatomy.pdf
If you want to allow <A> or <IMG> tags, you should use preg_match expressions for elementary sanity checking.
Je fume. Tu fumes. Nous fûmes!