CVE-2026-77422 Overview
JLine is a Java library for handling console input, widely embedded in interactive shells and remote command-line interfaces. CVE-2026-77422 is a Regular Expression Denial of Service (ReDoS) vulnerability in the built-in grep command implemented in builtins/src/main/java/org/jline/builtins/PosixCommands.java. The command accepts a user-controlled regular expression and, unless line-regexp mode is enabled, wraps it with .* prefix and suffix before compiling it with Java's backtracking engine. A short nested-quantifier pattern evaluated against non-matching input can consume excessive CPU and indefinitely block the command worker. The flaw affects JLine versions 3.0.0 through 3.30.14 and 4.x prior to 4.3.1.
Critical Impact
A remote user with access to a JLine-backed shell can freeze command worker threads by submitting a crafted grep pattern, causing sustained CPU exhaustion.
Affected Products
- JLine 3.0.0 through 3.30.14 (fixed in 3.30.15)
- JLine 4.x prior to 4.3.1 (fixed in 4.3.1)
- Applications embedding JLine's builtins module with remote shell exposure
Discovery Timeline
- 2026-09-23 - CVE-2026-77422 published to NVD
- 2026-09-23 - Last updated in NVD database
Technical Details for CVE-2026-77422
Vulnerability Analysis
The vulnerability is an instance of Inefficient Regular Expression Complexity [CWE-1333]. The grep(...) method in PosixCommands.java compiles a user-supplied pattern using java.util.regex.Pattern, which relies on a backtracking NFA engine. When line-regexp mode is not selected, JLine automatically wraps the input as .*<user_pattern>.* so the pattern can match anywhere in a line. The wrapping dramatically expands the backtracking search space for patterns containing nested quantifiers.
When the resulting expression is evaluated against non-matching input, the engine explores an exponential number of paths before failing. The regex evaluation runs inside the same thread that services the shell command, so the worker blocks until the match completes. In remotely exposed shells, a single crafted invocation is sufficient to make the interactive session unresponsive and drive one CPU core to full utilization.
Root Cause
The root cause is combining two unsafe design choices in the same code path: accepting untrusted regex input and silently wrapping it with .* on both sides before compilation. Java's default Matcher provides no execution timeout, so a pathological pattern such as (a+)+$ becomes catastrophic once the surrounding .* forces the engine to reconsider every prefix and suffix. The Less built-in command shares the same regex handling pattern and was patched in the same commit.
Attack Vector
An attacker interacts with any application that exposes JLine's built-in grep command over a remote channel, such as an SSH-backed administrative shell, a management console, or an embedded scripting REPL. The attacker submits a grep invocation whose pattern contains nested quantifiers. No authentication beyond shell access is required, and no user interaction is needed after submission. See the JLine3 Security Advisory GHSA-r2xf-8xr9-62gw for the full advisory.
// Patch excerpt: Commands.java adds SafeRegex import to guard against catastrophic backtracking
import org.jline.terminal.Terminal;
import org.jline.utils.AttributedStringBuilder;
import org.jline.utils.AttributedStyle;
+import org.jline.utils.SafeRegex;
import org.jline.utils.StyleResolver;
import static org.jline.builtins.SyntaxHighlighter.*;
Source: JLine3 Commit Fix
Detection Methods for CVE-2026-77422
Indicators of Compromise
- Java process hosting a JLine shell sustaining 100% CPU on a single thread for extended periods
- Thread dumps showing worker threads blocked inside java.util.regex.Pattern$*.match frames while executing PosixCommands.grep
- Unresponsive interactive sessions immediately following a grep command with a complex pattern
Detection Strategies
- Inventory Java applications and dependency manifests for org.jline:jline-builtins versions below 3.30.15 or 4.3.1
- Instrument shell command auditing to log full grep invocations, then flag patterns containing nested quantifiers such as (a+)+, (a*)*, or (a|a)+
- Enable JVM CPU profiling or async-profiler on shell hosts to identify long-running regex evaluations
Monitoring Recommendations
- Alert on Java thread CPU time exceeding a defined threshold within a single shell session
- Monitor SSH or management-console session duration and per-session CPU consumption for outliers
- Track application logs for grep commands that never return output, indicating the worker is stalled
How to Mitigate CVE-2026-77422
Immediate Actions Required
- Upgrade JLine to version 3.30.15 on the 3.x branch or 4.3.1 on the 4.x branch
- Restrict access to remote shells backed by JLine to trusted, authenticated users only
- Disable the built-in grep command in exposed shells where it is not required
Patch Information
The fix is delivered in JLine release 3.30.15 and release 4.3.1. The upstream commits 1d5fc3099e and 341ee69ccc introduce a SafeRegex utility and route both Commands.java and Less.java regex evaluations through it. Additional context is available in Pull Request #2012 and Pull Request #2018.
Workarounds
- Force line-regexp mode when invoking grep to bypass the .* wrapping that expands the backtracking space
- Wrap regex evaluation in a bounded executor with a hard timeout to abort runaway matches
- Reject user-supplied patterns containing nested quantifiers at the application layer before passing them to JLine
# Maven: pin the patched JLine version in pom.xml
mvn versions:set-property -Dproperty=jline.version -DnewVersion=3.30.15
# Gradle: enforce the patched version
# implementation('org.jline:jline:3.30.15')
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

