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-builtinsDetails
### 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
4.0.0Fixed in: 4.3.1# pom.xml: bump <version>4.3.1</version> for org.jline:jline-builtins3.0.0Fixed in: 3.30.15# pom.xml: bump <version>3.30.15</version> for org.jline:jline-builtinsReferences
- https://github.com/jline/jline3/security/advisories/GHSA-r2xf-8xr9-62gw[WEB]
- https://github.com/jline/jline3/pull/2012[WEB]
- https://github.com/jline/jline3/pull/2018[WEB]
- https://github.com/jline/jline3/commit/1d5fc3099e77938b971e197211cad2d4fbb17541[WEB]
- https://github.com/jline/jline3/commit/341ee69ccc57b7733c1b40d6993219b64b3206ae[WEB]
- https://github.com/jline/jline3[PACKAGE]
- https://github.com/jline/jline3/releases/tag/4.3.1[WEB]
- https://github.com/jline/jline3/releases/tag/jline-3.30.15[WEB]