A Billion More Laughs: The JavaScript hack that acts like an XML attack

Don is off in Lowell working on a project with our ARX folks so I was working late last night (finishing my daily read of the Internet) and ended up reading Scott Hanselman's discussion of threads versus processes in Chrome and IE8. It was a great read, if you like that kind of thing (I do), and it does a great job of digging into some of the RAMifications (pun intended) of the new programmatic models for both browsers.

But this isn't about processes or threads, it's about an interesting comment that caught my eye:

This will make IE8 Beta 2 unresponsive


..
t = document.getElementById("test");
while(true)
{
t.innerHTML += "a";
}

What really grabbed my attention is that this little snippet of code is so eerily similar to the XML "Billion Laughs" exploit, in which an entity is expanded recursively for, well, forever and essentially causes a DoS attack on whatever system (browser, server) was attempting to parse the document.

What makes scripts like this scary is that many forums and blogs that are less vehement about disallowing HTML and script can be easily exploited by a code snippet like this, which could cause the browser of all users viewing the infected post to essentially "lock up". This is one of the reasons why IE8 and Chrome moved to a more segregated tabbed model, with each tab basically its own process rather than a thread - to prevent corruption in one from affecting others. But given the comment this doesn't seem to be the case with IE8 (there's no indication Chrome was tested with this code, so whether it handles the situation or not is still to be discovered).

This is likely because it's not a corruption, it's valid JavaScript. It just happens to be consuming large quantities of memory very quickly and not giving the other processes in other tabs in IE8 a chance to execute.

The reason the JavaScript version was so intriguing was that it's nearly impossible to stop. The XML version can be easily detected and prevented by an XML firewall and most modern XML parsers can be configured to stop parsing and thus prevent the document from wreaking havoc on a system. But this JavaScript version is much more difficult to detect and thus prevent because it's code and thus not confined to a specific format with specific syntactical attributes. I can think of about 20 different versions of this script - all valid and all of them different enough to make pattern matching or regular expressions useless for detection. And I'm no evil genius, so you can bet there are many more.

The best option for addressing this problem? Disable scripts.

The conundrum is that disabling scripts can cause many, many sites to become unusable because they are taking advantage of AJAX functionality, which requires...yup, scripts. You can certainly enable scripts only on specific sites you trust (which is likely what most security folks would suggest should be default behavior anyway) but that's a PITA and the very users we're trying to protect aren't likely to take the time to do this - or even understand why it's necessary.

With the increasing dependence upon scripting to provide functionality for RIAs (Rich Interactive Applications) we're going to have to figure out how to address this problem, and address it soon. Eliminating scripting is not an option, and a default deny policy (essentially whitelisting) is unrealistic.

Perhaps it's time for signed scripts to make a comeback.

AddThis Feed Button Bookmark and Share

Published Sep 11, 2008
Version 1.0
  • @k3n

     

     

    The script does not crash NoScript. In fact, NoScript is one of the *best* ways to deal with poorly behaving/bad scripts, which is why it's included.

     

     

    NoScript isn't a panacea, but it does help make more manageable the process of disallowing/allowing scripts to run.

     

     

    Lori
  • @unknown_coder

     

     

    My understanding is that FF does warn you. The comment referenced IE8 beta 2, so it's possible this is something that Microsoft will address before officially releasing IE8.

     

     

    I agree, IE8 and Chrome *should* implement that same mechanism - and given that Google implemented its own JavaScript engine, one wonders if they did. I have not verified that it does or does not.

     

     

    Anyone want to try it with Chrome and let us know?
  • Another option is to control what you know. Javascript is fine as long as you are the one including it. Disable Javascript for all non-known entities (ie, comments, trackbacks, etc). This could help a bit...

     

     

    -Joe
  • @7rans

     

     

    That's a great point. I was actually thinking about that late yesterday. If you control the parsing, you control the stack, so you control how many iterations of the same piece of code is executed. Doesn't seem like rocket science at all.

     

     

    I say that blithely because *I* don't have to implement it. ;-) I seem to recall that writing compilers was ... interesting if not a bit frustrating.