VDB
Sign up
HIGH7.5

GHSA-r2xf-8xr9-62gw

JLine: ReDoS in Built-in grep Command Amplified by Automatic `.*` Wrapping

Quick fix

GHSA-r2xf-8xr9-62gw — org.jline:jline-builtins: upgrade to the fixed version with the command below.

# pom.xml: bump <version>4.3.1</version> for org.jline:jline-builtins

Details

### Summary

The JLine3 built-in `grep` command wraps the user-supplied regular expression with `.*` before compiling it with Java's backtracking regex engine. This amplifies catastrophic backtracking and allows a short pattern such as `(a+)+b` to hang the command thread on non-matching input. In environments that expose the JLine shell to remote users, this is a denial-of-service issue.

### Details

In `builtins/src/main/java/org/jline/builtins/PosixCommands.java`, the grep implementation rewrites the user pattern before compilation:

```java String regex = args.remove(0); String regexp = regex; if (opt.isSet("word-regexp")) { regexp = "\\b" + regexp + "\\b"; } if (opt.isSet("line-regexp")) { regexp = "^" + regexp + "$"; } else { regexp = ".*" + regexp + ".*"; } ```

The transformed pattern is compiled with `Pattern.compile(...)` and then used to test each input line. For a payload such as `(a+)+b`, the automatic `.*` prefix and suffix increase the backtracking search space substantially.

Affected source location: - `builtins/src/main/java/org/jline/builtins/PosixCommands.java` - `grep(...)`

### PoC

1. Create a file containing a long run of `a` characters:

```sh printf 'aaaaaaaaaaaaaaaaaaaaaaa\n' > /tmp/testfile.txt ```

2. Run JLine3's built-in `grep` against that file:

```sh grep '(a+)+b' /tmp/testfile.txt ```

Expected result: - The command stops responding. - The executing thread consumes high CPU.

Reproduction environment: - JLine3 on x86_64 Linux - OpenJDK 25.0.2

### Impact

This is a denial-of-service vulnerability caused by catastrophic regex backtracking. Any application embedding `org.jline:jline-builtins` and exposing the built-in `grep` command is impacted. In remote shell deployments, an attacker can occupy a worker thread indefinitely and repeat the attack across multiple sessions to reduce service availability for other users.

### Suggested Fix

The preferred fix for the current git head is: - stop rewriting non-line-regexp searches as `.*...*` - use `Matcher.find()` for substring semantics - compile user patterns with a linear-time engine such as RE2/J

Suggested patch:

```diff diff --git a/builtins/pom.xml b/builtins/pom.xml --- a/builtins/pom.xml +++ b/builtins/pom.xml @@ <dependency> + <groupId>com.google.re2j</groupId> + <artifactId>re2j</artifactId> + <version>1.8</version> + </dependency> + <dependency> <groupId>org.jline</groupId> <artifactId>jline-reader</artifactId> </dependency>

diff --git a/builtins/src/main/java/org/jline/builtins/PosixCommands.java b/builtins/src/main/java/org/jline/builtins/PosixCommands.java --- a/builtins/src/main/java/org/jline/builtins/PosixCommands.java +++ b/builtins/src/main/java/org/jline/builtins/PosixCommands.java @@ -import java.util.regex.Pattern; +import com.google.re2j.Pattern; @@ if (opt.isSet("line-regexp")) { regexp = "^" + regexp + "$"; - } else { - regexp = ".*" + regexp + ".*"; } @@ - boolean m = p.matcher(line).matches(); + boolean m = opt.isSet("line-regexp") + ? p.matcher(line).matches() + : p.matcher(line).find(); ```

### Credits

This issue was identified by Michał Majchrowicz and Marcin Wyczechowski, members of the AFINE Team.

Are you affected?

Enter the version of the package you're using.

Affected packages

Maven/org.jline:jline-builtins
Introduced in: 4.0.0Fixed in: 4.3.1
Fix# pom.xml: bump <version>4.3.1</version> for org.jline:jline-builtins
Maven/org.jline:jline-builtins
Introduced in: 3.0.0Fixed in: 3.30.15
Fix# pom.xml: bump <version>3.30.15</version> for org.jline:jline-builtins

References