Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Performance issue with malicious BigDecimal input, InstantDeserializer, DurationDeserializer (CVE-2018-1000873) #90

Closed
cowtowncoder opened this issue Oct 24, 2018 · 8 comments
Labels
CVE Vulnerability (usually with matching Mitre CVE id)
Milestone

Comments

@cowtowncoder
Copy link
Member

(note: moved from FasterXML/jackson-databind#2141 reported by @plokhotnyuk)

It looks the same as: playframework/play-json#180

Reproduced by the following commit: plokhotnyuk/jsoniter-scala@0d53faf

The security bug is in InstantDeserializer and DurationDeserializer of the jackson-datatype-jsr310 artifact:

    protected T _fromDecimal(DeserializationContext context, BigDecimal value)
    {
        long seconds = value.longValue();   // <- hangs in case of 10000000e100000000 
        int nanoseconds = DecimalUtils.extractNanosecondDecimal(value, seconds);
        return fromNanoseconds.apply(new FromDecimalArguments(
                seconds, nanoseconds, getZone(context)));
    }

W/A is to use custom serializers for all types that are parsed with InstantDeserializer and DurationDeserializer by registering them after (or instead of) registration of the JavaTimeModule module.

@cowtowncoder
Copy link
Member Author

(copied from above-mentioned original issue; comment by @plokhotnyuk)

Current implementations of java.math.BigInteger and java.math.BigDecimal in Java 8+ use binary (base-2) representation and during parsing translate provided decimal (base-10) representation to binary one:

https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/52fdb973403401f4073df3849793e1415ca2bc93/jdk/src/share/classes/java/math/BigInteger.java

https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/52fdb973403401f4073df3849793e1415ca2bc93/jdk/src/share/classes/java/math/BigDecimal.java

Below are results of benchmarks for different JSON parsers for Scala (including Jackson-module-scala) which are parametrized by the size parameter that specifies number of significant digits in scala.math.BigInt (which is just a wrapper over java.math.BigInteger):

[info] REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
[info] why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
[info] experiments, perform baseline and negative tests that provide experimental control, make sure
[info] the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
[info] Do not assume the numbers tell you what you want them to tell.
[info] Benchmark                              (size)   Mode  Cnt         Score         Error  Units
[info] BigIntBenchmark.readAVSystemGenCodec        1  thrpt    5  14890392.293 ±  590175.129  ops/s
[info] BigIntBenchmark.readAVSystemGenCodec       10  thrpt    5   6771799.312 ±  258856.674  ops/s
[info] BigIntBenchmark.readAVSystemGenCodec      100  thrpt    5   1507693.582 ±   35178.285  ops/s
[info] BigIntBenchmark.readAVSystemGenCodec     1000  thrpt    5     56379.543 ±    1754.682  ops/s
[info] BigIntBenchmark.readAVSystemGenCodec    10000  thrpt    5       721.463 ±      22.906  ops/s
[info] BigIntBenchmark.readAVSystemGenCodec   100000  thrpt    5         7.452 ±       0.043  ops/s
[info] BigIntBenchmark.readAVSystemGenCodec  1000000  thrpt    5         0.078 ±       0.001  ops/s
[info] BigIntBenchmark.readCirce                   1  thrpt    5   9128874.145 ±  206652.546  ops/s
[info] BigIntBenchmark.readCirce                  10  thrpt    5   7261855.082 ±  357869.830  ops/s
[info] BigIntBenchmark.readCirce                 100  thrpt    5    446646.616 ±   14351.238  ops/s
[info] BigIntBenchmark.readCirce                1000  thrpt    5     20715.338 ±     303.567  ops/s
[info] BigIntBenchmark.readCirce               10000  thrpt    5       488.270 ±      32.506  ops/s
[info] BigIntBenchmark.readCirce              100000  thrpt    5         6.606 ±       0.487  ops/s
[info] BigIntBenchmark.readJacksonScala            1  thrpt    5   5203959.437 ±  288410.893  ops/s
[info] BigIntBenchmark.readJacksonScala           10  thrpt    5   2754737.373 ±  137166.533  ops/s
[info] BigIntBenchmark.readJacksonScala          100  thrpt    5    923723.753 ±   32844.855  ops/s
[info] BigIntBenchmark.readJacksonScala         1000  thrpt    5     47777.094 ±    2031.990  ops/s
[info] BigIntBenchmark.readJacksonScala        10000  thrpt    5       670.702 ±      27.796  ops/s
[info] BigIntBenchmark.readJacksonScala       100000  thrpt    5         7.170 ±       0.159  ops/s
[info] BigIntBenchmark.readJacksonScala      1000000  thrpt    5         0.075 ±       0.001  ops/s
[info] BigIntBenchmark.readJsoniterScala           1  thrpt    5  60184573.095 ± 1329210.574  ops/s
[info] BigIntBenchmark.readJsoniterScala          10  thrpt    5  30459292.738 ±  751977.834  ops/s
[info] BigIntBenchmark.readJsoniterScala         100  thrpt    5   1384704.308 ±   11719.557  ops/s
[info] BigIntBenchmark.readNaiveScala              1  thrpt    5  29224139.625 ± 2260565.546  ops/s
[info] BigIntBenchmark.readNaiveScala             10  thrpt    5  11295523.994 ±  204324.161  ops/s
[info] BigIntBenchmark.readNaiveScala            100  thrpt    5   2024505.047 ±   17078.738  ops/s
[info] BigIntBenchmark.readNaiveScala           1000  thrpt    5     62508.755 ±    1824.931  ops/s
[info] BigIntBenchmark.readNaiveScala          10000  thrpt    5       765.462 ±       5.213  ops/s
[info] BigIntBenchmark.readNaiveScala         100000  thrpt    5         7.770 ±       0.191  ops/s
[info] BigIntBenchmark.readNaiveScala        1000000  thrpt    5         0.077 ±       0.001  ops/s
[info] BigIntBenchmark.readPlayJson                1  thrpt    5   9070015.382 ±  671907.068  ops/s
[info] BigIntBenchmark.readPlayJson               10  thrpt    5   7680490.729 ±  193593.896  ops/s
[info] BigIntBenchmark.readPlayJson              100  thrpt    5   1177518.121 ±   96448.882  ops/s
[info] BigIntBenchmark.readPlayJson             1000  thrpt    5     56525.825 ±    1110.685  ops/s
[info] BigIntBenchmark.readPlayJson            10000  thrpt    5       746.515 ±       9.304  ops/s
[info] BigIntBenchmark.readPlayJson           100000  thrpt    5         7.724 ±       0.077  ops/s
[info] BigIntBenchmark.readPlayJson          1000000  thrpt    5         0.072 ±       0.012  ops/s

To run them on your JDK:

  1. Install latest version of sbt and/or ensure that it already installed properly:
sbt about
  1. Clone jsoniter-scala repo:
git clone https://github.com/plokhotnyuk/jsoniter-scala.git
  1. Enter to the cloned directory:
cd jsoniter-scala
  1. Run benchmarks using a path parameter to your JDK:
sbt -no-colors 'jsoniter-scala-benchmark/jmh:run -jvm /usr/lib/jvm/jdk-11/bin/java -wi 5 -i 5 .*BigIntBench.*read.*'

@cowtowncoder cowtowncoder changed the title Performance issue with malicious BigDecimal input Performance issue with malicious BigDecimal input, InstantDeserializer, DurationDeserializer Oct 24, 2018
@cowtowncoder cowtowncoder added this to the 2.9.8 milestone Oct 24, 2018
@cowtowncoder
Copy link
Member Author

Fixed via #87, to be included in 2.9.8 and later.

@ddillard
Copy link

Any plans to get a CVE for this issue? If not, I can request one.

@cowtowncoder
Copy link
Member Author

@ddillard Not aware of one. If you can do that, that'd be helpful!

@ddillard
Copy link

@cowtowncoder Ok, I'll submit a request and post here when it's approved. Usually takes a few weeks to get one and given the holidays I wouldn't be surprised if takes a bit longer.

@ddillard
Copy link

Good news! Kurt got to this really quickly and this issue has been assigned CVE-2018-1000873. Should get published in the NVD in the next few days.

@cowtowncoder cowtowncoder changed the title Performance issue with malicious BigDecimal input, InstantDeserializer, DurationDeserializer Performance issue with malicious BigDecimal input, InstantDeserializer, DurationDeserializer (CVE-2018-1000873) Dec 21, 2018
@datagitlies
Copy link

@cowtowncoder are there any plans to fix this CVE in the 2.8 branch and cut a new release there? I'd volunteer to submit a pull request as #87 didn't look too complex. However, I can't help with the release part. Thoughts?

@cowtowncoder
Copy link
Member Author

@datagitlies No plans to backport as I really want to close 2.8 branch and any time spent on releasing from pre-2.9 is away from limited amount of time I have for my OSS hobby.
In this case patch would need to involve multiple components, for general DoS protection (jackson-core and jackson-databind have some, as well as this module).
So, I appreciate your offer to help, but I don't think I want to work on backport here.

dwaynebailey pushed a commit to hmcts/ccd-data-store-api that referenced this issue Jan 25, 2019
Upstream is not fixing this issue in 2.8.x we need to upgrade to at
least >= 2.9.8.
Ref
FasterXML/jackson-modules-java8#90 (comment)

RDM-3796
dwaynebailey pushed a commit to hmcts/ccd-definition-store-api that referenced this issue Jan 25, 2019
Upstream is not fixing this issue in 2.8.x we need to upgrade to at
least >= 2.9.8.
Ref
FasterXML/jackson-modules-java8#90 (comment)

RDM-3796
dwaynebailey pushed a commit to hmcts/ccd-data-store-api that referenced this issue Jan 29, 2019
Upstream is not fixing this issue in 2.8.x we need to upgrade to at
least >= 2.9.8.
Ref
FasterXML/jackson-modules-java8#90 (comment)

RDM-3796
dwaynebailey pushed a commit to hmcts/ccd-data-store-api that referenced this issue Jan 31, 2019
Upstream is not fixing this issue in 2.8.x we need to upgrade to at
least >= 2.9.8.
Ref
FasterXML/jackson-modules-java8#90 (comment)

RDM-3796
@cowtowncoder cowtowncoder added the CVE Vulnerability (usually with matching Mitre CVE id) label Apr 26, 2020
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
CVE Vulnerability (usually with matching Mitre CVE id)
Projects
None yet
Development

No branches or pull requests

3 participants