When Widgets Go Wrong
When I'm curious about tomorrow's weather (or need a quick look at a calendar), then I'll often invoke my laptop's Dashboard: It's a platform for Widgets, small applications written in HTML, CSS, and JavaScript -- Web technology, moved to the local host. These widgets provide front-ends to all kinds of information sources on the Web; several thousand are available for download. Obviously, the use of Web technologies has been a huge success here, enabling people to adapt their programming experience from the Web to their local platform. Apple's Dashboard is, of course, not the only platform: Google, Yahoo, Microsoft, and Opera have widget (or gadget) engines of their own; W3C's Web Application Formats Working Group has catalogued the properties of the various platforms in its widgets requirements document, and is working on a standard packaging format for widgets.
With the Web programming platform, though, come the Web's programming practices and security issues, sometimes with more serious consequences than before.
Let's begin with a classical piece of bad programming: Parsing data by evaluating it as code.
JSON stands for JavaScript Object Notation; it means using
JavaScript constant expressions as a way to transport structured data over the network. The
easiest way to parse that data format consists in evaluating it as code. JavaScript has an
eval()
primitive that comes in usefully: It takes a string and interprets it.
Now, one can argue that that's just the same thing as including another script, so it's not
really a big deal when done in the client-side part of a Web Application. The effect is,
after all, limited to one application, and that application's server-side code will have to
deal with hostlie clients anyway.
However, while Widgets might feel a lot like the usual Web environment to the programmer, they
really aren't: The limitations on what JavaScript code in a Widget can do are (sometimes
vastly) different. For instance, the Dashboard has a widget.system
method
available; that method takes a string and executes it as a Unix shell script. Effectively,
JavaScript has acquired an interface to the operating system. The question what scripts (or
widgets) one executes has become the same question as the one what programs one installs. A
widget that evaluates JSON data is now a way for an attacker to turn an attack against, say, a
service like Twitter, or against your local network,
into an attack that takes over an entire machine. That problem isn't just academic: Unsafe
JSON parsing is a regrettably common programming practice among widget authors. And your
web browsing behavior is intercepted whenever you're asked to pay at a commercial wireless
hotspot. Exploiting these attacks is easy.
eval()
isn't the only way to create this kind of attack surface: Using callback based JSON programming
techniques by inserting <script>
tags into a widget's document object
model creates exactly the same kind of vulnerability.
But there's more: You might have heard of cross-site-scripting vulnerabilities as, for instance, the source of the recent Orkut worm. The problem here is that a Web application takes input from some untrusted source and writes it into the HTML that it generates, without paying proper attention to escaping tags that an attacker might have placed in that input. The attacker can then inject scripts into the Web application's output, and these scripts can confuse clients' behavior. Now, what has that to do with widgets? Consider that widgets use an HTML document as their user interface. Any data that are presented to the user are written to the that document by JavaScript code.
That JavaScript code might quite well use techniques like the non-standard
innerHTML
DOM property to add a large fragment of HTML to the user interface. If
the data that are written to that property come from an untrusted source (e.g., the network),
and aren't properly sanitized, then an attacker can once again get scripts executed.
The Google Gmail widget was an example for that kind of code, until quite recently. Here, HTML tags in an e-mail's subject header were written into the widget's UI without checking. The effect was stunning: One e-mail with the right JavaScript in the subject header was enough to take over the recipient's computer, if that recipient was running the Gmail widget. Google has now fixed the problem in this widget.
But Google isn't alone: There are more widgets out there with this kind of vulnerability. Triggering the vulnerability might not take an e-mail, but involve a network attack, or, maybe, a malicious blog post, a photo description, or some interaction on a social networking site. Or the widget itself might come from a malicious source. The point here is that we're dealing with a shift in what Web-style programming can achieve -- and that that shift does not come without risk, and responsibility. A shift, incidentally, that extends beyond just Widgets, as Web technology is also becoming the programming platform of choice for mobile devices, and as the capabilities of Web applications that run in the classical browser are extended.
Addressing this risk and responsibility will require work both inside the "Web industry" proper (and in the W3C Working Groups where it meets, including the Web Application Formats and Web API WGs), and with the broader community: This is a problem that extends beyond just the platform.
PS: I hope explore this space more at this year's Chaos Communication Congress in Berlin, and maybe at next year's Web Conference.
Comments (0)
Comments for this post are closed.