question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Denial of service when parsing a big JSON number as Instant/ZonedDateTime/OffsetDateTime

See original GitHub issue

It looks the same as: https://github.com/playframework/play-json/issues/180

Reproduced by the following commit: https://github.com/plokhotnyuk/jsoniter-scala/pull/153/commits/0d53faf5093b492867b550f2cec55ff0b5cc62de

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.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:15
  • Comments:27 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
GotoFinalcommented, Oct 1, 2018

@abracadv8 would longValueExact be enough? if we want long anyway then it might be good idea to throw exception if number is too large/low, and this will do everything for you. Also @plokhotnyuk note that similar operation is inside DecimalUtils: https://github.com/FasterXML/jackson-modules-java8/blob/b45e632dbf4911c49cf33d2e8da5eb31113d1d75/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/DecimalUtils.java#L101 And this will hang too.

1reaction
plokhotnyukcommented, Oct 12, 2018

@cowtowncoder More over, it seems that during parsing of any JSON object it is possible to DoS the Jackson parser by just adding a field with the big number.

Here is a PR which initially reproduced it for Play-JSON parser:

https://github.com/plokhotnyuk/jsoniter-scala/pull/168/files

Below are results of parametrized benchmarks where the size parameter specifies a number of digits in the value of that additional field:

[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] ExtractFieldsBenchmark.readAVSystemGenCodec        1  thrpt    5   3415309.675 ± 358732.424  ops/s
[info] ExtractFieldsBenchmark.readAVSystemGenCodec       10  thrpt    5   3429891.871 ± 135960.100  ops/s
[info] ExtractFieldsBenchmark.readAVSystemGenCodec      100  thrpt    5    686235.263 ± 832769.728  ops/s
[info] ExtractFieldsBenchmark.readAVSystemGenCodec     1000  thrpt    5    194588.852 ±   8165.939  ops/s
[info] ExtractFieldsBenchmark.readAVSystemGenCodec    10000  thrpt    5     28335.193 ±    911.581  ops/s
[info] ExtractFieldsBenchmark.readAVSystemGenCodec   100000  thrpt    5      2948.038 ±    128.163  ops/s
[info] ExtractFieldsBenchmark.readAVSystemGenCodec  1000000  thrpt    5       649.088 ±    199.346  ops/s
[info] ExtractFieldsBenchmark.readCirce                   1  thrpt    5   1181495.148 ± 302987.993  ops/s
[info] ExtractFieldsBenchmark.readCirce                  10  thrpt    5   1277915.025 ± 179880.016  ops/s
[info] ExtractFieldsBenchmark.readCirce                 100  thrpt    5   1277950.564 ± 256709.663  ops/s
[info] ExtractFieldsBenchmark.readCirce                1000  thrpt    5    816515.741 ±  15529.900  ops/s
[info] ExtractFieldsBenchmark.readCirce               10000  thrpt    5    146038.446 ±   2585.134  ops/s
[info] ExtractFieldsBenchmark.readCirce              100000  thrpt    5     16825.855 ±    468.669  ops/s
[info] ExtractFieldsBenchmark.readCirce             1000000  thrpt    5      1693.840 ±     59.649  ops/s
[info] ExtractFieldsBenchmark.readDslJsonJava             1  thrpt    5  11703558.471 ± 196574.764  ops/s
[info] ExtractFieldsBenchmark.readDslJsonJava            10  thrpt    5  10418348.204 ± 125349.933  ops/s
[info] ExtractFieldsBenchmark.readDslJsonJava           100  thrpt    5   4854474.847 ± 335999.431  ops/s
[info] ExtractFieldsBenchmark.readDslJsonJava          1000  thrpt    5    833174.664 ±  22787.464  ops/s
[info] ExtractFieldsBenchmark.readDslJsonJava         10000  thrpt    5     88047.329 ±    894.533  ops/s
[info] ExtractFieldsBenchmark.readDslJsonJava        100000  thrpt    5      9037.421 ±     97.407  ops/s
[info] ExtractFieldsBenchmark.readDslJsonJava       1000000  thrpt    5       918.420 ±     13.473  ops/s
[info] ExtractFieldsBenchmark.readJacksonScala            1  thrpt    5   2533509.752 ±  75854.375  ops/s
[info] ExtractFieldsBenchmark.readJacksonScala           10  thrpt    5   2521299.318 ±  37344.857  ops/s
[info] ExtractFieldsBenchmark.readJacksonScala          100  thrpt    5    868736.640 ±  19590.367  ops/s
[info] ExtractFieldsBenchmark.readJacksonScala         1000  thrpt    5     54637.764 ±   1922.976  ops/s
[info] ExtractFieldsBenchmark.readJacksonScala        10000  thrpt    5       723.644 ±     14.444  ops/s
[info] ExtractFieldsBenchmark.readJacksonScala       100000  thrpt    5         7.254 ±      0.414  ops/s
[info] ExtractFieldsBenchmark.readJacksonScala      1000000  thrpt    5         0.077 ±      0.001  ops/s
[info] ExtractFieldsBenchmark.readJsoniterScala           1  thrpt    5  17357927.186 ± 105168.663  ops/s
[info] ExtractFieldsBenchmark.readJsoniterScala          10  thrpt    5  15509884.192 ± 599007.176  ops/s
[info] ExtractFieldsBenchmark.readJsoniterScala         100  thrpt    5  10557719.687 ±  82797.425  ops/s
[info] ExtractFieldsBenchmark.readJsoniterScala        1000  thrpt    5   2306588.382 ±  15014.663  ops/s
[info] ExtractFieldsBenchmark.readJsoniterScala       10000  thrpt    5    252999.473 ±   2013.190  ops/s
[info] ExtractFieldsBenchmark.readJsoniterScala      100000  thrpt    5     24022.123 ±    490.780  ops/s
[info] ExtractFieldsBenchmark.readJsoniterScala     1000000  thrpt    5      2042.339 ±    118.757  ops/s
[info] ExtractFieldsBenchmark.readPlayJson                1  thrpt    5    928062.700 ±  35964.755  ops/s
[info] ExtractFieldsBenchmark.readPlayJson               10  thrpt    5    908324.771 ±  41278.052  ops/s
[info] ExtractFieldsBenchmark.readPlayJson              100  thrpt    5    538588.245 ±  58035.196  ops/s
[info] ExtractFieldsBenchmark.readPlayJson             1000  thrpt    5     52739.058 ±   5124.015  ops/s
[info] ExtractFieldsBenchmark.readPlayJson            10000  thrpt    5       743.426 ±      6.226  ops/s
[info] ExtractFieldsBenchmark.readPlayJson           100000  thrpt    5         7.351 ±      0.030  ops/s
[info] ExtractFieldsBenchmark.readPlayJson          1000000  thrpt    5         0.067 ±      0.018  ops/s
[info] ExtractFieldsBenchmark.readUPickle                 1  thrpt    5   3340922.046 ± 246892.139  ops/s
[info] ExtractFieldsBenchmark.readUPickle                10  thrpt    5   3483490.433 ±  39971.435  ops/s
[info] ExtractFieldsBenchmark.readUPickle               100  thrpt    5   2494567.445 ±  71404.382  ops/s
[info] ExtractFieldsBenchmark.readUPickle              1000  thrpt    5    814753.180 ±  30787.779  ops/s
[info] ExtractFieldsBenchmark.readUPickle             10000  thrpt    5    101384.553 ±   1049.347  ops/s
[info] ExtractFieldsBenchmark.readUPickle            100000  thrpt    5     10380.287 ±     43.464  ops/s
[info] ExtractFieldsBenchmark.readUPickle           1000000  thrpt    5       991.119 ±     60.797  ops/s

Step to reproduce are same as before, except the names of branch and benchmark:

  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 and checkout the play-json-DoS-using-big-number branch:
cd jsoniter-scala
chackout play-json-DoS-using-big-number
  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 .*ExtractFieldBench.*read.*'
Read more comments on GitHub >

github_iconTop Results From Across the Web

5 JSON Denial Attack that Every Hacker Take Advantage Of
A Denial Of Service attack is an attack to disrupt the normal service of the targeted server. Just like how a huge amount...
Read more >
Denial of Service (DoS) in json | CVE-2020-10663 | Snyk
When parsing certain JSON documents, the json gem (including the one bundled with Ruby) can be coerced into creating arbitrary objects in the ......
Read more >
Parsing fails in a big JSON - javascript - Stack Overflow
I can open the JSON with a program called Huge JSON Viewew, which means that the file is well structured, but when it...
Read more >
An Exploration of JSON Interoperability Vulnerabilities
Denial-of-Service : Segmentation Faults. Two parsing libraries crashed on malformed JSON. Both of these instances have been reported to the ...
Read more >
SyntaxError: JSON.parse: bad parsing - JavaScript | MDN
The JavaScript exceptions thrown by JSON.parse() occur when string failed to be ... JSON.parse: unterminated string SyntaxError: JSON.parse: no number after ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found