Shescape: Quadratic-Time Denial of Service in Flag Protection
A crafted input string fed to any Shescape escape or quote function causes the flag-protection logic to run in quadratic time, letting an attacker freeze a Node.js server with a moderately large…

The problem
Shescape versions 2.1.11 through 2.1.13 include a flag-protection feature that is enabled by default. That feature uses a regular expression to detect and neutralize leading dash prefixes that could be interpreted as CLI flags.
The regex has quadratic (O(n²)) complexity when the input contains repeated null-byte-plus-dash sequences. An attacker who can supply input to any of escape, escapeAll, quote, or quoteAll can cause the Node.js process to stall for tens of seconds with an input of roughly 64,000 characters, amounting to a denial of service.
Proof of concept
A working proof-of-concept for this issue in shescape, with the exact payload below.
import { Shescape } from "shescape";
// flagProtection is true by default, no special config needed
const shescape = new Shescape();
// 64 000 chars; each \u0000- pair drives quadratic regex backtracking
const payload = "\u0000-".repeat(32000);
const t0 = process.hrtime.bigint();
shescape.escape(payload);
const ms = Number(process.hrtime.bigint() - t0) / 1e6;
console.log("Duration ms:", ms); // ~20 000 ms on an unpatched buildThe flag-protection path in the vulnerable versions strips leading dash/slash prefixes by repeatedly applying a regex over the input string. The pattern catastrophically backtracks when the input mixes null bytes (U+0000) and dashes, because the alternation inside the regex re-attempts partial matches at every character position, producing O(n²) work.
The patch (commits b4b34c3 for v2, 43d70b5 for v3) rewrites the prefix-stripping logic to use a linear string scan instead of a backtracking-capable regex. After the fix, runtime scales linearly with input length regardless of content.
The fix
Upgrade to shescape v2.1.14 (or v3.0.1 if already on v3). If upgrading immediately is not possible, enforce a maximum input length before calling any Shescape function, or strip all content before the last dash in untrusted input. Note that v2 reaches end-of-life on 2026-09-28, so migrating to v3 is recommended.
Related research
- criticalshescape: Shell Injection via Unescaped Parentheses on Windows CMD
- highCVE-2026-55685CVE-2026-55685: react-router Unauthenticated DoS via Inefficient Route Matching on Manifest Endpoint
- highCVE-2026-59880CVE-2026-59880: immutable Hash-Collision Algorithmic Complexity DoS
- high · 7.5CVE-2026-59869CVE-2026-59869: js-yaml Merge-Key Chain Quadratic CPU DoS