Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stack overflow error caused by dsl-json serialization Map #256

Open
PoppingSnack opened this issue Jun 8, 2023 · 2 comments
Open

Stack overflow error caused by dsl-json serialization Map #256

PoppingSnack opened this issue Jun 8, 2023 · 2 comments

Comments

@PoppingSnack
Copy link

Stack overflow error caused by dsl-json serialization Map

Description

dsl-json before v1.10.0 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.util.HashMap.hash(HashMap.java:340)
	at java.base/java.util.HashMap.put(HashMap.java:608)
	at java.base/java.util.HashSet.add(HashSet.java:220)
	at com.dslplatform.json.ExternalConverterAnalyzer.tryFindConverter(ExternalConverterAnalyzer.java:15)
	at com.dslplatform.json.DslJson.checkExternal(DslJson.java:1097)
	at com.dslplatform.json.DslJson.lookupFromFactories(DslJson.java:1125)
	at com.dslplatform.json.DslJson.tryFindWriter(DslJson.java:1057)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2757)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2759)
	at com.dslplatform.json.DslJson.serialize(DslJson.java:2912)
	at com.dslplatform.json.DslJson.serializeMap(DslJson.java:1339)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:550)
	at com.dslplatform.json.DslJson$3.write(DslJson.java:543)


PoC

<dependency>
	<groupId>com.dslplatform</groupId>
	<artifactId>dsl-json</artifactId>
	<version>1.10.0</version>
</dependency>
import com.dslplatform.json.DslJson;

import java.io.ByteArrayOutputStream;
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);
        DslJson<Object> dslJson = new DslJson<>();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            dslJson.serialize(map, byteArrayOutputStream);
        } 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. (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
@zapov
Copy link
Member

zapov commented Jun 9, 2023

Tnx for the report, but I'm not really sure how this is Denial of service via a crafted string? Can you show that?

While we can certainly introduce depth tracking, there are still ways in which you can create "endless/broken" serialization.

@zapov
Copy link
Member

zapov commented Jun 11, 2023

I'm assuming it cant cause DoS and as far as cycles go, this issue is a duplicate of #55

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants