HarperFast / HarperFast/harper

[security] ReDoS: attacker-controlled SQL LIKE pattern compiled to an unbounded per-row regex

Open
#1,930 1 comment 0 reactions 0 assignees View on GitHub
area:security
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

**Severity:** MEDIUM · **Category:** `redos` · **CWE-1333**
**Location:** `sqlEngine/expressions/compile.ts:306` in `likeToRegex`

## Impact
A single crafted query hangs the Node worker's event loop for seconds-to-effectively-forever, denying service to every other request handled by that worker; repeated queries wedge the process.

## Details
The untrusted LIKE pattern from a request's WHERE clause is turned into a RegExp with %→.* and no length or quantifier sanitization (the '*' metacharacter is not even escaped), then run per row via re.test, so a crafted pattern causes catastrophic backtracking that blocks the worker.

## Exploit scenario
An authenticated user issues SELECT * FROM data.t WHERE name LIKE '%_%_%_%_%_%_%_%_%_%_%_%_%_%_Z' after inserting a row whose name is a long run of non-'Z' characters. likeToRegex yields ^.*..*..*...Z$ and re.test backtracks catastrophically, pinning a CPU and blocking the worker while it evaluates the filter.

## Preconditions
- sql.engine is 'auto' (default) or 'new' so the new engine plans the query
- requester is authenticated with permission to run a SELECT/UPDATE/DELETE whose WHERE contains a LIKE
- the compared column value is long enough (attacker can INSERT one) for backtracking to blow up

## Recommended fix
Escape '*' along with the other metacharacters, cap the pattern length, and compile the regex once outside the per-row eval (hoist likeToRegex out of the row closure). Prefer a non-backtracking matcher or a linear LIKE implementation, and reject patterns that expand beyond a safe bound.

---
Found by an automated multi-agent security review (Claude Security) against `origin/main` @ `2615b092b`, confirmed by a three-lens verification panel. Line numbers are as of that commit. No code was executed; derived from source review, so validate before remediation.

Contributor guide

Open the contributing guide

Research direction

Start in sqlEngine/expressions/compile.ts at likeToRegex around line 306, then trace how the compiled expression is evaluated per row. Validate the reported LIKE-to-RegExp behavior and choose a bounded, non-backtracking or linear matching approach. Done means attacker-controlled patterns cannot cause catastrophic backtracking or repeated per-row compilation while LIKE queries retain their expected behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, sql, typescript
Domain
backend, databases, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.