Skip to content

Fix ReDoS in chessboard FEN sanitize (/ .+$/) used by examples/wchess #3374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

wukunyu264
Copy link

What does this PR do?

Reports and fixes a potential Regular Expression Denial of Service (ReDoS) in the FEN–sanitize step of the embedded chessboard script. With a crafted input the regex can cause extremely high CPU usage and freeze the process.

File:
examples/wchess/wchess.wasm/chessboardjs-1.0.0/js/chessboard-1.0.0.js

Before

fen = fen.replace(/ .+$/, '');

After (fix)

// eliminate catastrophic backtracking by removing the overlap after the space
fen = fen.replace(/ (?! ).+$/, '');

Why is this needed?

The pattern / .+$/ is vulnerable to catastrophic backtracking.
When the input looks like:

" ".repeat(N) + "\n@"

. does not cross the newline, while $ forces a match at end-of-string; the leading space overlaps with the first set of .+, so the engine backtracks quadratically from each starting space. This leads to long stalls (tens of seconds on common hardware).

The new pattern adds a negative lookahead (?! ) to ensure the .+ part does not start with another space, removing the overlap and making the match linear-time. For valid FEN (which uses a single space after the position), behavior is unchanged. Inputs with multiple consecutive spaces are intentionally not trimmed (safer semantics).

Alternative safe forms (if preferred) with equivalent performance:

// forbid crossing newlines without lookahead ($ no longer needed)
fen = fen.replace(/ [^\n]*$/, '');
// or avoid regex entirely:
const i = fen.indexOf(' '); fen = i === -1 ? fen : fen.slice(0, i);

How I reproduced and verified

before:
image

after:
屏幕截图 2025-08-13 165059

step:
git clone https://github.com/wukunyu264/whisper.cpp.git
cd whisper.cpp
npm i --prefix js-tests
cd js-tests
npm test

Type of change

  • Bugfix

Backwards compatibility

  • No breaking change for valid FEN strings (single space separator).
  • Stricter behavior for malformed inputs with consecutive spaces (they are no longer trimmed), which is safer.

Security / performance impact

  • Removes a ReDoS vector in the example’s JavaScript path.
  • Changes worst-case complexity from super-linear backtracking to O(n).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant