Title: Prevent Double.parseDouble() attacks
Type: Severity: normal
Components: Core Versions: 2.5.2rc
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: otmarhumbel Nosy List: otmarhumbel, pjenvey
Priority: Keywords:

Created on 2011-02-08.12:40:02 by otmarhumbel, last changed 2011-02-12.11:13:05 by otmarhumbel.

File name Uploaded Description Edit Remove
SafeDecimalParser-patch.txt otmarhumbel, 2011-02-08.12:40:01
DoubleTroubleTestSuite.jar otmarhumbel, 2011-02-08.12:45:42
DoubleTroubleTestSuite.jar otmarhumbel, 2011-02-12.08:48:22 Test suite containing all the sources
msg6387 (view) Author: Oti Humbel (otmarhumbel) Date: 2011-02-08.12:40:01
Lately there has been quite of rumour in the Java community about the endless loop caused by a certain range of values.
Jython could be brought into such an endless loop simply by assigning the right value to a variable, such as
  value = a_bad_value

The Java hot spots are the following:
- BigDecimal.doubleValue()
- BigDecimal.floatValue()
- Double(String)
- Double.parseDouble(String)
- Double.valueOf(String)
- Float(String)
- Float.parseFloat(String)
- Float.valueOf(String)

The attached patch prevents these kind of attacks by replacing our usage of the hot spots above by a safer parsing strategy:

1) look for suspicious digits in the input string (heuristic, but quite fast)
2a) for suspicious values: use BigDecimal to safely parse them
2b) fix the real dangerous values by 'rounding' them to safe ones (outside the dangerous interval) 
For non-suspicious values, use the default fast Double parsing, as before

The performance penalty in the majority of cases is the detection of suspiciousness:

final protected static boolean isSuspicious(String s) {
  return digits(s).indexOf(SUSPICIOUS_DIGITS) >= 0;

final private static String digits(String s) {
  char[] ca = s.toCharArray();
  int len = ca.length;
  StringBuilder b = new StringBuilder(len);
  for (int i = 0; i < len; i++) {
    char c = ca[i];
    if (c >= '0' && c <= '9') {
  return b.toString();

Two questions:
 - does this sound reasonable ?
 - if yes, should we build that into 2.5.2 final ?
msg6388 (view) Author: Oti Humbel (otmarhumbel) Date: 2011-02-08.12:45:42
DoubleTroubleTestSuite.jar runs all the tests for the safer parsers.
It contains non jython specific java sources as well.
msg6389 (view) Author: Philip Jenvey (pjenvey) Date: 2011-02-09.17:47:16
I'm not sure this is really worth the effort, since it's such a publicized  problem I expect a fix for the JVM will be released soon. One of the perks of running on top of the JVM is we can defer fixes like this to the JVM hackers

This blog post says it can be reproduced with a number of different numbers:

Sounds like it would be hard to detect them all as a workaround. The core integer parsing routine really needs a fix applied there
msg6390 (view) Author: Oti Humbel (otmarhumbel) Date: 2011-02-10.11:27:32
Oracle already fixed the issue:

Maybe we'll need the workaround for older, unpatched versions of java.
If this should be the case, we can bury it out.
The workaround would detect all values in the actually known dangerous interval.
msg6396 (view) Author: Oti Humbel (otmarhumbel) Date: 2011-02-12.08:48:22
The first DoubleTroubleTestSuite.jar did not contain all sources.
msg6397 (view) Author: Oti Humbel (otmarhumbel) Date: 2011-02-12.11:13:05
Just had an email conversation with Charles Oliver Nutter. JRuby probably builds in this safety net.
Should we do as well, maybe for rc4?
Date User Action Args
2011-02-12 11:13:05otmarhumbelsetmessages: + msg6397
2011-02-12 08:48:23otmarhumbelsetfiles: + DoubleTroubleTestSuite.jar
messages: + msg6396
2011-02-10 11:27:32otmarhumbelsetstatus: open -> closed
resolution: wont fix
messages: + msg6390
2011-02-09 17:47:16pjenveysetnosy: + pjenvey
messages: + msg6389
2011-02-08 12:45:43otmarhumbelsetfiles: + DoubleTroubleTestSuite.jar
messages: + msg6388
2011-02-08 12:40:02otmarhumbelcreate