VYPR
Critical severityNVD Advisory· Published Jul 17, 2024· Updated Aug 2, 2024

Eclipse Parsson stack overflow with deeply nested objects

CVE-2023-7272

Description

Eclipse Parsson before 1.0.4 and 1.1.3 is vulnerable to denial of service via a stack overflow from parsing deeply nested JSON objects.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Eclipse Parsson before 1.0.4 and 1.1.3 is vulnerable to denial of service via a stack overflow from parsing deeply nested JSON objects.

Eclipse Parsson, a Jakarta JSON Processing implementation, contains a vulnerability where parsing a JSON document with an excessive depth of nested objects can cause a Java stack overflow exception, leading to a denial of service [1]. The root cause is the lack of a depth limit during parsing, allowing recursive processing to exhaust the call stack [2].

An attacker can exploit this by providing a crafted JSON input with deeply nested structures to an application that uses Parsson to parse untrusted JSON data. No authentication is required; any service exposing a JSON parsing endpoint is vulnerable [1][2].

Successful exploitation results in a Denial of Service (DoS) due to the application crashing with a StackOverflowError [2]. This can disrupt availability for legitimate users.

The issue is fixed in versions 1.0.4 and 1.1.3, where a default maximum nesting depth of 1000 is enforced, with the ability to configure this limit via the MAX_DEPTH property [3]. Users should upgrade or apply the fix to mitigate the vulnerability.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.eclipse.parsson:parssonMaven
>= 1.1.0, < 1.1.31.1.3
org.eclipse.parsson:parssonMaven
< 1.0.41.0.4

Affected products

2

Patches

2
d0ec79badd44

#91: Stack overflow error caused by jakarta.json parsing of untrusted JSON String

https://github.com/eclipse-ee4j/parssonLukas JungmannJul 12, 2023via ghsa
4 files changed · +125 1
  • impl/src/main/java/org/eclipse/parsson/api/JsonConfig.java+6 0 modified
    @@ -34,6 +34,12 @@ public interface JsonConfig {
          */
         String MAX_BIGDECIMAL_LEN = "org.eclipse.parsson.maxBigDecimalLength";
     
    +    /**
    +     * Configuration property to limit maximum level of nesting when being parsing JSON string.
    +     * Default value is set to {@code 1000}.
    +     */
    +    String MAX_DEPTH = "org.eclipse.parsson.maxDepth";
    +
         /**
          * Configuration property to reject duplicate keys.
          * The value of the property could be anything.
    
  • impl/src/main/java/org/eclipse/parsson/JsonContext.java+12 0 modified
    @@ -40,6 +40,9 @@ final class JsonContext {
         /** Default maximum number of characters of BigDecimal source being parsed. */
         private static final int DEFAULT_MAX_BIGDECIMAL_LEN = 1100;
     
    +    /** Default maximum level of nesting. */
    +    private static final int DEFAULT_MAX_DEPTH = 1000;
    +
         /**
          * Custom char[] pool instance property. Can be set in properties {@code Map} only.
          */
    @@ -53,6 +56,9 @@ final class JsonContext {
         // Maximum number of characters of BigDecimal source
         private final int bigDecimalLengthLimit;
     
    +    // Maximum depth to parse
    +    private final int depthLimit;
    +
         // Whether JSON pretty printing is enabled
         private final boolean prettyPrinting;
     
    @@ -70,6 +76,7 @@ final class JsonContext {
         JsonContext(Map<String, ?> config, BufferPool defaultPool) {
             this.bigIntegerScaleLimit = getIntConfig(JsonConfig.MAX_BIGINTEGER_SCALE, config, DEFAULT_MAX_BIGINTEGER_SCALE);
             this.bigDecimalLengthLimit = getIntConfig(JsonConfig.MAX_BIGDECIMAL_LEN, config, DEFAULT_MAX_BIGDECIMAL_LEN);
    +        this.depthLimit = getIntConfig(JsonConfig.MAX_DEPTH, config, DEFAULT_MAX_DEPTH);
             this.prettyPrinting = getBooleanConfig(JsonGenerator.PRETTY_PRINTING, config);
             this.rejectDuplicateKeys = getBooleanConfig(JsonConfig.REJECT_DUPLICATE_KEYS, config);
             this.bufferPool = getBufferPool(config, defaultPool);
    @@ -86,6 +93,7 @@ final class JsonContext {
         JsonContext(Map<String, ?> config, BufferPool defaultPool, String... properties) {
             this.bigIntegerScaleLimit = getIntConfig(JsonConfig.MAX_BIGINTEGER_SCALE, config, DEFAULT_MAX_BIGINTEGER_SCALE);
             this.bigDecimalLengthLimit = getIntConfig(JsonConfig.MAX_BIGDECIMAL_LEN, config, DEFAULT_MAX_BIGDECIMAL_LEN);
    +        this.depthLimit = getIntConfig(JsonConfig.MAX_DEPTH, config, DEFAULT_MAX_DEPTH);
             this.prettyPrinting = getBooleanConfig(JsonGenerator.PRETTY_PRINTING, config);
             this.rejectDuplicateKeys = getBooleanConfig(JsonConfig.REJECT_DUPLICATE_KEYS, config);
             this.bufferPool = getBufferPool(config, defaultPool);
    @@ -109,6 +117,10 @@ int bigDecimalLengthLimit() {
             return bigDecimalLengthLimit;
         }
     
    +    int depthLimit() {
    +        return depthLimit;
    +    }
    +
         boolean prettyPrinting() {
             return prettyPrinting;
         }
    
  • impl/src/main/java/org/eclipse/parsson/JsonParserImpl.java+14 1 modified
    @@ -55,25 +55,28 @@ public class JsonParserImpl implements JsonParser {
         private Context currentContext = new NoneContext();
         private Event currentEvent;
     
    -    private final Stack stack = new Stack();
    +    private final Stack stack;
         private final JsonTokenizer tokenizer;
         private boolean closed = false;
     
         private final JsonContext jsonContext;
     
         public JsonParserImpl(Reader reader, JsonContext jsonContext) {
             this.jsonContext = jsonContext;
    +        stack = new Stack(jsonContext.depthLimit());
             this.tokenizer = new JsonTokenizer(reader, jsonContext);
         }
     
         public JsonParserImpl(InputStream in, JsonContext jsonContext) {
             this.jsonContext = jsonContext;
    +        stack = new Stack(jsonContext.depthLimit());
             UnicodeDetectingInputStream uin = new UnicodeDetectingInputStream(in);
             this.tokenizer = new JsonTokenizer(new InputStreamReader(uin, uin.getCharset()), jsonContext);
         }
     
         public JsonParserImpl(InputStream in, Charset encoding, JsonContext jsonContext) {
             this.jsonContext = jsonContext;
    +        stack = new Stack(jsonContext.depthLimit());
             this.tokenizer = new JsonTokenizer(new InputStreamReader(in, encoding), jsonContext);
         }
     
    @@ -380,9 +383,18 @@ public void close() {
         // Using the optimized stack impl as we don't require other things
         // like iterator etc.
         private static final class Stack {
    +        int size = 0;
    +        final int limit;
             private Context head;
     
    +        Stack(int size) {
    +            this.limit = size;
    +        }
    +
             private void push(Context context) {
    +            if (++size >= limit) {
    +                throw new RuntimeException("Input is too deeply nested " + size);
    +            }
                 context.next = head;
                 head = context;
             }
    @@ -391,6 +403,7 @@ private Context pop() {
                 if (head == null) {
                     throw new NoSuchElementException();
                 }
    +            size--;
                 Context temp = head;
                 head = head.next;
                 return temp;
    
  • impl/src/test/java/org/eclipse/parsson/tests/JsonNestingTest.java+93 0 added
    @@ -0,0 +1,93 @@
    +/*
    + * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
    + *
    + * This program and the accompanying materials are made available under the
    + * terms of the Eclipse Public License v. 2.0, which is available at
    + * http://www.eclipse.org/legal/epl-2.0.
    + *
    + * This Source Code may also be made available under the following Secondary
    + * Licenses when the conditions for such availability set forth in the
    + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    + * version 2 with the GNU Classpath Exception, which is available at
    + * https://www.gnu.org/software/classpath/license.html.
    + *
    + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
    + */
    +
    +package org.eclipse.parsson.tests;
    +
    +import jakarta.json.Json;
    +import jakarta.json.stream.JsonParser;
    +import org.junit.Test;
    +
    +import java.io.StringReader;
    +
    +public class JsonNestingTest {
    +
    +    @Test(expected = RuntimeException.class)
    +    public void testArrayNestingException() {
    +        String json = createDeepNestedDoc(500);
    +        try (JsonParser parser = Json.createParser(new StringReader(json))) {
    +            while (parser.hasNext()) {
    +                JsonParser.Event ev = parser.next();
    +                if (JsonParser.Event.START_ARRAY == ev) {
    +                    parser.getArray();
    +                }
    +            }
    +        }
    +    }
    +
    +    @Test
    +    public void testArrayNesting() {
    +        String json = createDeepNestedDoc(499);
    +        try (JsonParser parser = Json.createParser(new StringReader(json))) {
    +            while (parser.hasNext()) {
    +                JsonParser.Event ev = parser.next();
    +                if (JsonParser.Event.START_ARRAY == ev) {
    +                    parser.getArray();
    +                }
    +            }
    +        }
    +    }
    +
    +    @Test(expected = RuntimeException.class)
    +    public void testObjectNestingException() {
    +        String json = createDeepNestedDoc(500);
    +        try (JsonParser parser = Json.createParser(new StringReader(json))) {
    +            while (parser.hasNext()) {
    +                JsonParser.Event ev = parser.next();
    +                if (JsonParser.Event.START_OBJECT == ev) {
    +                    parser.getObject();
    +                }
    +            }
    +        }
    +    }
    +
    +    @Test
    +    public void testObjectNesting() {
    +        String json = createDeepNestedDoc(499);
    +        try (JsonParser parser = Json.createParser(new StringReader(json))) {
    +            while (parser.hasNext()) {
    +                JsonParser.Event ev = parser.next();
    +                if (JsonParser.Event.START_OBJECT == ev) {
    +                    parser.getObject();
    +                }
    +            }
    +        }
    +    }
    +
    +    private static String createDeepNestedDoc(final int depth) {
    +        StringBuilder sb = new StringBuilder();
    +        sb.append("[");
    +        for (int i = 0; i < depth; i++) {
    +            sb.append("{ \"a\": [");
    +        }
    +        sb.append(" \"val\" ");
    +        for (int i = 0; i < depth; i++) {
    +            sb.append("]}");
    +        }
    +        sb.append("]");
    +        return sb.toString();
    +    }
    +
    +}
    
755d2a86dff7

add JDK 21 to GH action build

https://github.com/eclipse-ee4j/parssonLukas JungmannMay 11, 2023via ghsa
1 file changed · +6 7
  • .github/workflows/pr.yml+6 7 modified
    @@ -1,5 +1,5 @@
     #
    -# Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation
    +# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
     #
     # This program and the accompanying materials are made available under the
     # terms of the Eclipse Public License v. 2.0 which is available at
    @@ -16,21 +16,20 @@ on:
       pull_request:
       push:
     
    +concurrency:
    +  group: ${{ github.ref }}
    +  cancel-in-progress: true
    +
     jobs:
       build:
         name: Test on JDK ${{ matrix.java_version }} 
         runs-on: ubuntu-latest
     
         strategy:
           matrix:
    -        java_version: [ 11, 17 ]
    +        java_version: [ 11, 17, 21-ea ]
     
         steps:
    -    - name: Cancel previous runs of this workflow
    -      uses: styfle/cancel-workflow-action@0.9.1
    -      with:
    -        all_but_latest: true
    -        access_token: ${{ github.token }}
         - name: Checkout for build
           uses: actions/checkout@v3
         - name: Set up JDK
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.