Wednesday, July 12, 2006

Privacy and Exploits - 4

CONTINUED FROM PREVIOUS

E
very nerd loves the XMLHttpRequest. It supplies the functionality of which Web programmers' dreams are made. Web applications start behaving like desktop applications. Things work as they're "supposed to," freeing the Mum-and-Dad end users from needing to know anything about servers, clients, post-backs and submit buttons—"Submit? Submit to what!"

Recently, a myriad of awesome examples have exploded onto the Web scene that illustrate why remote scripting (or "AJAX" if you prefer), is the greatest thing since the one-pixel gif. In fact, the list of cool and useful applications seems to be growing daily, with sites such as Flickr, Google Maps Gmail, etc.

Those sites and others have created an avalanche of AJAX hype. To be fair, the technology does have the potential to improve the online experience. For all its goodness, however, something smells a little funny about this Web communication; like beer and chocolate before it, there is an evil side to what—on the surface—seems pure and innocent.

The underlying potential for evil exists in the important functional differences that hide behind the user-interface mask of familiarity. Many of you have been using the Internet for 10 years now and you know how it works: You click around; you fill out forms; you tweak or fix your entries, and you hit the Submit button when you're done. You know the essentials that have been passed down from Web generations to newbie Web generations, such as: "Don't press the Submit button twice—the form might get double-posted," or "Wait a bit longer, it's just processing," or "Don't press the 'back' button after you've submitted the form," and so on.

But you can throw that basic knowledge out of the window now that AJAX is in town. It's "anything goes," and suddenly there's a swag of newly trackable data available to be sent at any time, without the user's knowledge—without the (average) user even knowing it's possible. Every keystroke, every mouse move, every click, every pause, can now be captured and sent to the Web server and there is nothing you can do about it.

XMLHttpRequest: Good vs. Evil
Like so many technologies-gone-bad before it, this technology was created for the purpose of good. And until now, the XMLHttpRequest has been so good it could almost be considered saintly, providing users and developers alike with such conveniences as input validation without post-back, text area spell checkers, and Gmail. Interfaces built with AJAX are fun to use and even more fun to program. It's almost hard to imagine that such a miraculous object could ever do wrong.

But even without the discovery of a giant security hole, the XMLHttpRequest will likely fall from grace. Its fall will be in the form of "user over-profiling" for want of a better description. Currently, user profiling helps Web site owners detect trends, track page viewing habits and iron out usability problems. Until now though, developers could only analyze posted data—data that users decided they wanted the server to get, and were happy to send off for processing.

But in a subtle shift, this balance of power has changed hands. With AJAX, a user's actions can be constantly and meticulously monitored. Because it can be done, it will be done, and that will lead to a headache bigger than just wasted bandwidth, terabytes of useless information, and slower page load times.

Just imagine, for the purposes of an example, that you drop your new iPod on the ground and it stops working. Hoping to get a free replacement, you write an e-mail to Apple support that says: "I just bought a brand new iPod. I dropped it down a set of stairs. It stopped working." You then decide to delete the second sentence to help your cause. TOO LATE! If the site uses AJAX, your response may already have been zapped to the complaint desk in the sky!

Or—a little more malevolently—consider this: most people have one or two username/password combinations that they use for all of their "unimportant" sites such as news sites, blogs, and forums. They probably also have a few reserved for use on more sensitive sites—banking, Web mail and work accounts. It's a very common and easy mistake to begin typing incorrect login details for a given page. Force of habit is responsible, but people usually realize what they've done before hitting the submit button.

Unfortunately, an AJAX keystroke logger is trivial to implement. Using such a keystroke logger, code can collect incorrect login attempts and later test them against a list of "important" sites—also using the XMLHttpRequest object, of course.

The "Evil" Implications
To be fair, most of the "evil" applications cited above could have been done reasonably well even before the XMLHttpRequest came along. Indeed, the request object is simply a more elegant method of accomplishing what submitting form data to an IFrame previously did. But the XMLHttpRequest works in a far more natural way, one that has the effect of eroding the distinction between client-side and server-side interaction.

It is ironic that only recently, with the popularity of the Firefox Web browser, have large numbers of users understood the depth and scope of information stored on and controlled by the Web client. With widespread adoption of tools such as Greasemonkey, Web developer extensions, and cookie editors, people feel more confident than ever that if it happens client-side then it belongs to the user.

But now, even the more paranoid of us can no longer just right-click, view source and be sure of what's going on. Consider the following OnReadyStateChange JavaScript function running in response to an XMLHttpRequest:

   xmlReq.onreadystatechange =
{
if( xmlReq.readyState == 4 )
{
eval( xmlReq.responseText );
}
}

That script executes the JavaScript code contained in the response from the XMLHttpRequest. In other words, it's possible to add or modify JavaScript functions and code in the background even after a page load! So even if you inspect the page source for code that might be sending keystrokes or mouse movements back to the Web server, you can't be certain that the code you see is the only code that's executing. Combine that with some funky obfuscation and you can see how malevolent intent and the XMLHttpRequest object can combine to steal security away from the Web client.

[INCOMPLETE...PLEASE READ THE ABOVE TEMPORARY POST]