bluelinelabs / bluelinelabs/LoganSquare
Stack overflow error caused by logansquare serialization List
- 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