VDB
Sign up
MEDIUM5.5

GHSA-5q95-hrpc-m3w3

JLine: ReDoS via `HISTORY_IGNORE` Configuration Variable

Quick fix

GHSA-5q95-hrpc-m3w3 — org.jline:jline-reader: upgrade to the fixed version with the command below.

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

Details

### Summary

The JLine3 `HISTORY_IGNORE` variable is converted into a Java regular expression with only partial escaping. As a result, regex metacharacters other than `*` and `:` are passed through to the regex engine. A crafted value such as `(a+)+b` can cause catastrophic backtracking each time a command line is added to history, hanging the reader thread at high CPU.

### Details

In `reader/src/main/java/org/jline/reader/impl/history/DefaultHistory.java`, `matchPatterns()` converts `HISTORY_IGNORE` into a regex:

```java for (int i = 0; i < patterns.length(); i++) { char ch = patterns.charAt(i); if (ch == '\\') { ch = patterns.charAt(++i); sb.append(ch); } else if (ch == ':') { sb.append('|'); } else if (ch == '*') { sb.append('.').append('*'); } else { sb.append(ch); } } return line.matches(sb.toString()); ```

This logic translates wildcard syntax but does not escape regex metacharacters such as `(`, `)`, `+`, `?`, `{`, `}`, `[`, and `]`. Those characters therefore reach the Java regex engine unchanged.

Affected source location: - `reader/src/main/java/org/jline/reader/impl/history/DefaultHistory.java` - `matchPatterns(String patterns, String line)`

### PoC

1. Configure `HISTORY_IGNORE` to a malicious pattern, for example:

```sh set history-ignore "(a+)+b" ```

2. At the JLine prompt, enter a long non-matching line:

```text aaaaaaaaaaaaaaaaaaaaaaaaaaax ```

3. Press Enter.

Expected result: - The prompt does not return. - The reader 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. Applications embedding `org.jline:jline-reader` are impacted if they allow `HISTORY_IGNORE` to be configured through user configuration or application settings. The issue is lower severity than the interactive editor findings because the attacker must control configuration, but it can still reliably hang a reader session.

### Suggested Fix

The safest fix for the current git head is to stop treating arbitrary `HISTORY_IGNORE` content as a regex. Instead, escape all characters by default and translate only the intended JLine wildcard syntax (`*`) and separator syntax (`:`).

Suggested patch:

```diff diff --git a/reader/src/main/java/org/jline/reader/impl/history/DefaultHistory.java b/reader/src/main/java/org/jline/reader/impl/history/DefaultHistory.java --- a/reader/src/main/java/org/jline/reader/impl/history/DefaultHistory.java +++ b/reader/src/main/java/org/jline/reader/impl/history/DefaultHistory.java @@ StringBuilder sb = new StringBuilder(); for (int i = 0; i < patterns.length(); i++) { char ch = patterns.charAt(i); if (ch == '\\') { ch = patterns.charAt(++i); - sb.append(ch); + sb.append(Pattern.quote(Character.toString(ch))); } else if (ch == ':') { sb.append('|'); } else if (ch == '*') { sb.append('.').append('*'); } else { - sb.append(ch); + sb.append(Pattern.quote(Character.toString(ch))); } } return line.matches(sb.toString()); ```

### 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-reader
Introduced in: 4.0.0Fixed in: 4.3.1
Fix# pom.xml: bump <version>4.3.1</version> for org.jline:jline-reader
Maven/org.jline:jline-reader
Introduced in: 3.0.0Fixed in: 3.30.15
Fix# pom.xml: bump <version>3.30.15</version> for org.jline:jline-reader

References