Tuesday, 8 February 2011
Java Denial of Service Vulnerability (Double Trouble)
Most versions of Java and some versions of PHP enter an infinite loop trying to turn the string "2.2250738585072012e-308" into a double precision floating point value. (Remember scientific notation? Floats and doubles are good for representing really big and really small numbers. Very important for getting the physicists to shell out for supercomputers.) Here are the details on the bugs.
This is a recipe for a quick and easy denial of service attack. If you have a Java application that does something as simple as this:
Double.parseDouble(request.getParameter("d"));
attackers can wedge a thread every time they make an HTTP request. Now Anonymous doesn't need a botnet army to take your app offline. A laptop with an AOL dialup connection should be plenty.
From a language perspective, the situation for PHP is worse because of PHP's type coercion (Looks like a double? Parse it like a double.) But only versions 5.2 and 5.3 of PHP are vulnerable, and the PHP team released a patch last month.
For Java, the problem isn't a single number. There is a small range of numbers that cause the conversion to hang. But there are lots of ways to write any given floating point number, so those itty-bitty numbers turn into an enormous volume of potential input strings. (For example, the strings "2.2250738585072012e-308" and "0.022250738585072012e-00306" are equally problematic.) The upshot is that an attack is difficult to block from the network layer without catching some legitimate values too.
The Tomcat Twist
Think you're not vulnerable because your program doesn't use any doubles? Wrong answer. Tomcat uses parseDouble() on the value of the Accept-Language HTTP header when an application calls request.getLocale(). If your application takes locale into account, chances are it's vulnerable. This isn't the only under-the-covers place doubles are lurking, so the absence of direct calls to methods such as Double.parseDouble() or Double.valueOf() doesn't mean you're guaranteed safe. And chances are good Tomcat isn't the only bit of Java middleware or framework code that uses a double.
The Punchline
This bug is an excellent example of the evolving software security landscape. Until this problem came along, calling parseDouble() looked like an ideal way to validate input. Now parseDouble() is yet another weak point to protect. And so it goes. When you ship software, you have to make sure it's protected against the risks we know about today. But when you wake up tomorrow, new risks may well have emerged during the night. Building secure systems means more than just avoiding foreseeable mistakes. It means preparing for the unforeseeable too. That means being ready to respond when new vulnerabilities emerge.
Next Steps
Oracle and Tomcat have released patches this week. We expect other Java providers (such as IBM) to follow suit. But it will be quite a while before those fixes are widely deployed. Until then, here's what we're doing:
- We have released a Fortify Real-Time Analyzer (RTA) rulepack that protects against the attack at the code level. It monitors calls to the underlying class and flags calls that will cause the thread to hang. If desired, it can patch the code so that the vulnerability no longer exists. All without taking the app offline. Just saying.
- Next week the HP Application Security Center (ASC) will release a check for WebInspect so that vulnerable applications can be identified during security testing.
- The next Fortify Secure Coding Rulepack update for SCA (to be released at the end of February) will include static analysis rules to detect code that is vulnerable to an attack on methods such as
parseDouble()andgetLocale().







