VYPR
Moderate severityNVD Advisory· Published Dec 29, 2023· Updated Aug 2, 2024

CVE-2023-50572

CVE-2023-50572

Description

CVE-2023-50572: jline-groovy v3.24.1 allows denial of service via OutOfMemory error through the GroovyEngine.execute component.

AI Insight

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

CVE-2023-50572: jline-groovy v3.24.1 allows denial of service via OutOfMemory error through the GroovyEngine.execute component.

Vulnerability

Overview

An issue in the GroovyEngine.execute component of jline-groovy v3.24.1 allows attackers to cause an OutOfMemory (OOM) error, leading to a denial of service [4]. The vulnerability is rooted in how the internalPrintln method handles long lines or large objects without proper constraints, specifically missing a maxrows parameter to limit output [2]. Without this limit, the highlightAndPrint method can process unlimited amounts of data, exhausting available heap memory [2][3].

Exploitation

To trigger the OOM condition, an attacker could provide crafted input that causes the GroovyEngine to generate excessively long strings or large JSON outputs [1][2]. The attack does not require authentication if the application exposes the console or script execution to untrusted users. The jline library is used for reading console input in Java applications, so any application that uses jline-groovy's REPL or scripting features with arbitrary input is potentially affected [1][3].

Impact

Successful exploitation results in a denial of service through memory exhaustion, which can crash the Java process or degrade system performance [4]. This could disrupt services relying on jline for terminal input/output operations, especially those processing large data structures or long lines without size validation.

Mitigation

The maintainers have addressed this issue by adding a maxrows parameter to limit the number of rows processed in internalPrintln and highlightAndPrint calls [2]. Users should update to a patched version of jline3 that includes the commit fixing the OOM vulnerability [2][3]. As of the publication date, no workaround is documented beyond applying the patch.

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.jline:jline-parentMaven
< 3.25.03.25.0

Affected products

2

Patches

1
f3c60a3e6255

GroovyEngine.execute cause an OOM exception, fixes #909

https://github.com/jline/jline3mattirnDec 15, 2023via ghsa
1 file changed · +20 12
  • console/src/main/java/org/jline/console/impl/DefaultPrinter.java+20 12 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002-2022, the original author(s).
    + * Copyright (c) 2002-2023, the original author(s).
      *
      * This software is distributable under the BSD license. See the terms of the
      * BSD license in the documentation provided with this software.
    @@ -337,14 +337,15 @@ private void internalPrintln(Map<String, Object> options, Object object) {
             String style = (String) options.getOrDefault(Printer.STYLE, "");
             options.put(Printer.STYLE, valueHighlighter(style));
             int width = (int) options.get(Printer.WIDTH);
    +        int maxrows = (int) options.get(Printer.MAXROWS);
             if (!style.isEmpty() && object instanceof String) {
    -            highlightAndPrint(width, (SyntaxHighlighter) options.get(Printer.STYLE), (String) object, true);
    +            highlightAndPrint(width, (SyntaxHighlighter) options.get(Printer.STYLE), (String) object, true, maxrows);
             } else if (style.equalsIgnoreCase("JSON")) {
                 if (engine == null) {
                     throw new IllegalArgumentException("JSON style not supported!");
                 }
                 String json = engine.toJson(object);
    -            highlightAndPrint(width, (SyntaxHighlighter) options.get(Printer.STYLE), json, true);
    +            highlightAndPrint(width, (SyntaxHighlighter) options.get(Printer.STYLE), json, true, maxrows);
             } else if (options.containsKey(Printer.SKIP_DEFAULT_OPTIONS)) {
                 highlightAndPrint(options, object);
             } else if (object instanceof Exception) {
    @@ -354,7 +355,7 @@ private void internalPrintln(Map<String, Object> options, Object object) {
             } else if (object instanceof String || object instanceof Number) {
                 String str = object.toString();
                 SyntaxHighlighter highlighter = (SyntaxHighlighter) options.getOrDefault(Printer.VALUE_STYLE, null);
    -            highlightAndPrint(width, highlighter, str, doValueHighlight(options, str));
    +            highlightAndPrint(width, highlighter, str, doValueHighlight(options, str), maxrows);
             } else {
                 highlightAndPrint(options, object);
             }
    @@ -464,14 +465,20 @@ private boolean doValueHighlight(Map<String, Object> options, String value) {
             }
         }
     
    -    private void highlightAndPrint(int width, SyntaxHighlighter highlighter, String object, boolean doValueHighlight) {
    -        for (String s : object.split("\\r?\\n")) {
    +    private void highlightAndPrint(
    +            int width, SyntaxHighlighter highlighter, String object, boolean doValueHighlight, int maxrows) {
    +        String[] rows = object.split("\\r?\\n", maxrows);
    +        int lastRowIdx = rows.length == maxrows ? rows.length - 1 : rows.length;
    +        for (int i = 0; i < lastRowIdx; i++) {
                 AttributedStringBuilder asb = new AttributedStringBuilder();
    -            List<AttributedString> sas = asb.append(s).columnSplitLength(width);
    +            List<AttributedString> sas = asb.append(rows[i]).columnSplitLength(width);
                 for (AttributedString as : sas) {
                     highlight(width, highlighter, as.toString(), doValueHighlight).println(terminal());
                 }
             }
    +        if (rows.length == maxrows) {
    +            throw new TruncatedOutputException("Truncated output: " + maxrows);
    +        }
         }
     
         private Map<String, Object> keysToString(Map<Object, Object> map) {
    @@ -749,6 +756,7 @@ private boolean isNumber(String str) {
         @SuppressWarnings("unchecked")
         private void highlightAndPrint(Map<String, Object> options, Object obj) {
             int width = (int) options.get(Printer.WIDTH);
    +        int maxrows = (int) options.get(Printer.MAXROWS);
             totLines = 0;
             String message = null;
             RuntimeException runtimeException = null;
    @@ -758,10 +766,9 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
                 highlightMap(options, keysToString((Map<Object, Object>) obj), width);
             } else if (collectionObject(obj)) {
                 List<Object> collection = objectToList(obj);
    -            if (collection.size() > (int) options.get(Printer.MAXROWS)) {
    -                message = "Truncated output: " + options.get(Printer.MAXROWS) + "/" + collection.size();
    -                collection =
    -                        collection.subList(collection.size() - (int) options.get(Printer.MAXROWS), collection.size());
    +            if (collection.size() > maxrows) {
    +                message = "Truncated output: " + maxrows + "/" + collection.size();
    +                collection = collection.subList(collection.size() - maxrows, collection.size());
                 }
                 if (!collection.isEmpty()) {
                     if (collection.size() == 1 && !options.containsKey(Printer.ONE_ROW_TABLE)) {
    @@ -771,7 +778,8 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
                         } else if (canConvert(elem) && !options.containsKey(Printer.TO_STRING)) {
                             highlightMap(options, objectToMap(options, elem), width);
                         } else if (elem instanceof String && options.get(Printer.STYLE) != null) {
    -                        highlightAndPrint(width, (SyntaxHighlighter) options.get(Printer.STYLE), (String) elem, true);
    +                        highlightAndPrint(
    +                                width, (SyntaxHighlighter) options.get(Printer.STYLE), (String) elem, true, maxrows);
                         } else {
                             highlightValue(options, null, objectToString(options, obj))
                                     .println(terminal());
    

Vulnerability mechanics

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

References

4

News mentions

0

No linked articles in our index yet.