The recent cross-platform numerical parsing DOS bug has been named the "Mark of the Beast". Some claim that this bug was first reported as early as 2001.
This is a significant bug in (at least) PHP and Java. Similar issues have effected Ruby in the past. This bug has left a number of servers, web frameworks and custom web applications vulnerable to easily exploitable Denial of Service.
This is a significant bug in (at least) PHP and Java. Similar issues have effected Ruby in the past. This bug has left a number of servers, web frameworks and custom web applications vulnerable to easily exploitable Denial of Service.
Oracle has patched this vuln but there are several non-Oracle JVM's that have yet to release a patch. Tactical patching may be prudent for environment.
Here are three filters that may help you tame this beast of a bug.
1) Ryan Barnett deployed a series of mod security rules and documented several options here http://blog.spiderlabs.com/2011/02/java-floating-point-dos-attack-protection.html
2) Bryan Sullivan from Adobe came up with the following Java-based blacklist filter. This rule is actually quite accurate in *rejecting input* in the DOSable JVM numeric range. This fix, while simple, does indeed reject a series of normally good values.
public static boolean containsMagicDoSNumber(String s) {
return s.replace(".", "").contains("2225073858507201");
}
private static BigDecimal bigBad;
private static BigDecimal smallBad;
static {
BigDecimal one = new BigDecimal(1);
BigDecimal two = new BigDecimal(2);
BigDecimal tiny = one.divide(two.pow(1022));
// 2^(-1022) 2^(-1076)
bigBad = tiny.subtract(one.divide(two.pow(1076)));
//2^(-1022) 2^(-1075)
smallBad = tiny.subtract(one.divide(two.pow(1075)));
}
if (input == null) throw new InvalidParameterException("input is null");
BigDecimal bd;
try {
bd = new BigDecimal(input);
} catch (NumberFormatException e) {
throw new InvalidParameterException("cant parse number");
}
if (bd.compareTo(smallBad) >= 0 && bd.compareTo(bigBad) <= 0) {
// if you get here you know you're looking at a bad value. The final
// value for any double in this range is supposed to be the following safe #
//return safe number
System.out.println("BAD NUMBER DETECTED - returning 2.2250738585072014E-308");
return new Double("2.2250738585072014E-308");
}
//safe number, return double value
return bd.doubleValue();
}
No comments:
Post a Comment