[go: up one dir, main page]

|
|
Log in / Subscribe / Register

Cross-site scripting attacks

April 12, 2006

This article was contributed by Jake Edge.

Two weeks ago, this page examined SQL injection attacks on web applications. Another well-known attack is cross-site scripting, often abbreviated as "XSS." Cross-site scripting is, perhaps, a more subtle way of breaking web applications, but its effects can be just as damaging as SQL Injection.

The basic vector for XSS is user input into a website that is not filtered to remove dangerous content. One of the more obvious ways this can occur is with sites that allow users to add comments to stories, without removing or altering HTML tags that they enter. For example, if one adds a comment that contains:

    <script>alert("howdy")</script>
and someone else, when looking at that comment, gets the alert, the site is vulnerable to XSS. Obviously, a javascript popup is not particularly dangerous and would be a clear sign that something odd is going on. This kind of 'attack' is only used as a proof of concept. The key thing to note is that one user can run javascript in the context of another user's browser, with all of the information and privileges of the targeted user (or, at least, the subset granted to javascript).

There are other mechanisms to inject this kind of malicious content, either as HTML links or by causing error messages that display the content. Essentially any place that a web application displays user input can be exploited if the input or output is not filtered correctly. When XSS attacks appear in links, they are often encoded in hex using the '%xx' or '&#xx;' so that it is not immediately apparent that the link contains malicious content.

A wide variety of actions can be triggered by an XSS exploit, including cookie theft, account hijacking, and denial of service. A clever attacker could make a page that looks exactly like the login page of a popular website (Google for example) and an unwary user could be fooled into entering their username and password into this page after following a link. By exploiting an XSS hole recently reported and discussed on the Bugtraq mailing list, the link would not obviously be malicious and could start with http://www.google.com.

Another common attack is to hijack a session by using an XSS exploit to capture a cookie value that stores a session ID. An attacker can then use that session ID to take over a currently logged-in session at the web site and for all intents and purposes, become that user. This attack is especially nasty if that user happens to be an administrative user - or is logged into, say, a financial site.

Avoiding XSS in a web application requires diligence in filtering user input (a common theme in nearly all web application vulnerabilities). Any user input that is sent back to browser for any reason needs to have certain characters converted to strings that will display properly, but not be interpreted as HTML by the browser. An XSS FAQ recommends replacing the following characters: < > ( ) & and # with &lt;, &gt;, &#40, etc.

XSS vulnerabilities are one of the most commonly reported security issues with web applications today. New XSS techniques are discovered regularly that find new ways to evade various security measures implemented by the browser scripting languages and new ways to fool users into falling into an XSS trap. Any technique that allows attackers to run code in your browser with your permissions is obviously cause for worry. Website users can only take some fairly drastic measures to avoid XSS (turning off javascript, not following links, etc.). This is clearly something that website owners must handle to protect their users.


Index entries for this article
GuestArticlesEdge, Jake


to post comments

Cross-site scripting attacks

Posted Apr 13, 2006 6:19 UTC (Thu) by jwb (guest, #15467) [Link] (5 responses)

I used to hunt around the web looking for cross-site scripting attacks at famous sites (stock
brokerages, banks, ISPs, etc) in 2000 and 2001. It is very sad to me that, five years later, I can
open a web browser, use the same screening techniques, and still find XSS vulnerabilities at
major commercial sites at the rate of several per day.

To protect a site from XSS, the developer really must abandon the decade-old practice of
communicating with the browser using the print function. The days of print "<html>" are over.
That technique should be shunned by any self-respecting developer. A better
implementation, which is immune to XSS, is to build your web pages on the server side using the
Document Object Model. The DOM can then be serialized to HTML (or XML) and sent to the
browser.

Why is the DOM method immune to XSS? Suppose you have some user-provided input which
contains malicious javascript. If you print(tainted), that malicious code will be send verbatim to
the browser and executed. If you instead use document.createTextNode(tainted), the tainted
input will be harmlessly added to the document tree as a text node (which is what you want;
there's no way for a text node to have any structural meaning in an XML document.) Later, when
you serialize the DOM to a byte stream, all text nodes will be harmlessly escaped.

Now, you might say that you want your users to be able to provide "rich" input, meaning you
want them to be able to enter a subset of HTML tags, usually for basic formatting. That's fine
and can be solved in the DOM method. You simply parse the user input into a new Document on
the server side, walk the document, and prune any nodes which are found to not be on a pre-
approved list of allowed nodeType/tagName combinations.

This may sound like a lot of programming, but it really isn't. Java, Perl, and C have perfectly
serviceable DOM implementations, and I'm sure other languages also have that feature. And
you'll find after you adopt this method that most server-side web programming is much easier.
The spaghetti code of print() calls drops away, and amazing new features, like actually removing
elements from your page, become possible.

That's just my suggestion, anyway.

Cross-site scripting attacks

Posted Apr 13, 2006 6:39 UTC (Thu) by Dom2 (guest, #458) [Link] (2 responses)

Personally, I think our tools our to blame. I wrote The Wrong Defaults a little while back to try and explain why.

-Dom

Cross-site scripting attacks

Posted Apr 13, 2006 6:52 UTC (Thu) by jwb (guest, #15467) [Link] (1 responses)

Having read your blog entry, it seems like you would agree that something like
document.createTextNode() does the right thing by default, no? If you stick to the DOM, there's no
way to inadvertently do something stupid. Everything, stupid or otherwise, is done explicitly.

Regarding your example of SQL placeholders, even that wisdom has not trickled down to the great
programming masses. The vast majority of PHP code out there in wild builds up SQL queries using
string concatenation and explicit escaping. Usually this means no or insufficient escaping. PHP
only recently acquired a decent interface for interacting with SQL databases, and the use of it is not
yet widespread.

Cross-site scripting attacks

Posted Apr 13, 2006 9:23 UTC (Thu) by Dom2 (guest, #458) [Link]

Yes, document.createTextNode() does do the right thing. But I was thinking more in terms of server side solutions like PHP, ASP and JSP. They default to "insecure".

-Dom

Cross-site scripting attacks

Posted Apr 13, 2006 14:48 UTC (Thu) by kingdon (guest, #4526) [Link]

Yes, yes, yes! Thank you for saying this.

Some systems that get the quoting right: DOM, tinytemplate, XmlWriter, Amrita (a ruby template engine), probably a few others.

Some systems that get the quoting wrong: jsp, velocity, rhtml (a ruby template engine, alas more popular than Amrita), print statements, m4 (or anything else not specific to XML/HTML), etc, etc, etc.

Maybe others can augment these lists with some of the popular engines out there for python and others.

Cross-site scripting attacks

Posted Apr 13, 2006 20:49 UTC (Thu) by iabervon (subscriber, #722) [Link]

For many applications, it's nicer to just have a print function that quotes everything it gets, and a separate printTag function that can be used to insert non-text. It's an easier conversion than switching to DOM, doesn't inherently require that the whole document be stored at once, and still fails safely (i.e., if you call printTag on a non-tag, it gives you and error; if you call print on a tag, it gives you the escaped version; either way, bugs in the normal case are quick to find and in attacks nothing happens).

The harder thing is actually cases where you want to permit some markup but not scripts, especially if what you're accepting is HTML fragments. (Not that people don't often screw up the easy cases.)

Of course, these problems should really be called HTML injection attacks, since they're essentially the same as SQL injection attacks: some content which is supposed to be a string literal is treated as structure. Of course, trying to do the equivalent of a prepared statement would be a bit less practical (use AJAX to get each variable region as a separate request and insert it as the appropriate type?).

XSS is for real

Posted Apr 13, 2006 16:23 UTC (Thu) by b7j0c (guest, #27559) [Link] (2 responses)

xss is definitely at the top of the security issues real users face every day, since most people spend a great deal of time surfing the web and xss exploits are so trivial to code. some things you can do as a user - run noscript for firefox. i cannot stress this enough. allow js for sites you need and trust. block all of the others. if you do not run noscript, assume your cookies have already been stolen, likely multiple times.

for content producers, prefer css to js where they provide complimentary functionality and where it is technically possible. this will also provide higher performance.

there is little point bemoaning the state of site exploits further, as most of the exploiters know what they are doing and are making money by mining data they steal.

even for technically astute users and developers, i can assure you that you will be shocked and amazed at what some of the advanced xss hackers can do.

XSS is for real

Posted Apr 20, 2006 16:36 UTC (Thu) by Duncan (guest, #6647) [Link] (1 responses)

Indeed, XSS is a very real security worry.

I agree with the no-script thing. Turning off Javascript "drastic", as
the article states? I don't /think/ so! Rather, it's been the default
here for a good eight years or more. Scripting (and back on MSWormOS,
ActiveHex, and on Linux, plugins) and cookies are always off by default,
only turned on after I find I need them and ask myself what trust level I
have for the site, and whether my need for what the site offers justifies
the necessary hassle. I can state for a fact that a site's poor choices
have not only redirected my viewing, but thousands of dollars worth of
purchases, over the years. If they aren't security conscious enough to
realize that some users visiting their site won't have certain things
enabled by default, and have the site designed so at least information
about a product can be gathered without /too/ much jumping thru hoops to
turn stuff back on, then they obviously aren't concerned enough about
security to be worth my purchasing consideration, whether it's a site I'm
shopping right then with card in hand, or a manufacturer's site I'm
looking at for product info. There are other sites out there plenty
willing to let me be their customer, without the hassle.

FWIW, tho, not FireFox here, but Konqueror, with its per-site scripting
and cookie permissions, and privoxy, filtering the worst stuff and setting
all cookies to session-only by default, before Konqueror even sees it.

Duncan

XSS is for real

Posted Apr 23, 2006 15:42 UTC (Sun) by anton (subscriber, #25547) [Link]

>Turning off Javascript "drastic", as the article states? I don't
>/think/ so! Rather, it's been the default here for a good eight years
>or more.

On my accounts, I always turn off JavaScript (and a bunch of other
stuff), and *never* turn it on. And as for you, that certainly
affects what I buy.


Copyright © 2006, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds