CVE Patch Review

GHSA-W4HW-QCX7-56PR: Root-cause Fix for Windows CMD Parenthesis Escaping in shescape

GHSA-W4HW-QCX7-56PR · Updated 2026-07-25 Root-cause

Summary

The patch addresses the disclosed Windows CMD command-injection issue by adding '(' and ')' to the CMD metacharacter escape set in src/internal/win/cmd.js and updating Windows fixtures accordingly. Based on the supplied diffs, this directly fixes the reported root cause for GHSA-W4HW-QCX7-56PR. The same changeset also includes unrelated Unix escaping and compose-path refactors, which increase review surface but do not weaken the Windows fix shown in the sources.

Analysis

Vulnerability

GHSA-W4HW-QCX7-56PR describes an OS command injection condition in shescape on Windows CMD when attacker-controlled input contains unescaped parentheses. In cmd.exe, ( and ) are control characters for command grouping, so failing to escape them allows input to alter parsing when embedded inside parenthesized command blocks. The vulnerable implementation in src/internal/win/cmd.js escaped % & < > ^ | but omitted parentheses, leaving a parser-breaking gap in the Windows escaping model. The advisory and patch references are consistent on this point: GHSA advisory, PR #2651, commit b4b34c3.

/* vulnerable */
const specials = new RegExp(/([%&<>^|])/g);

/* patched */
const specials = new RegExp(/([%&()<>^|])/g);

The Windows fixture updates further confirm intended behavior changes for literal parentheses, e.g. inputs previously expected to remain a(b or a) are now expected to become a^(b and a^), matching CMD caret-escaping semantics shown in the patch sources: PR #2649, commit 43d70b5.

Patch

The security-relevant Windows change is minimal and targeted: the regular expression defining CMD-special characters now includes both ( and ). This means the existing escaping pipeline will treat parentheses as metacharacters and prefix them with the CMD escape character ^. The associated test fixture changes validate multiple placements of both characters, including leading, trailing, nested, and mixed forms such as a(b)c becoming a^(b^)c. These are the exact cases needed to close the parser-confusion primitive described by the advisory.

expected: "a^(b",
expected: "a^(b^(c",
expected: "a^(",
expected: "^(a",
expected: "a^)b",
expected: "a^)b^)c",
expected: "a^)",
expected: "^)a",
expected: "a^(b^)c",

The same patch series also modifies Unix escaping logic in src/internal/unix/dash.js and src/internal/unix/zsh.js, expands Unix fixtures, and refactors src/internal/compose.js. Those changes appear to address separate escaping correctness issues and test behavior, as documented in the changelog entries linked from PR #2651 and PR #2649. For GHSA-W4HW-QCX7-56PR specifically, the decisive fix is the CMD regex update in src/internal/win/cmd.js.

Review

Pros

  • The patch directly addresses the identified root cause: missing escaping for CMD grouping metacharacters ( and ).
  • The implementation is low-risk and localized to the Windows CMD escaping table in src/internal/win/cmd.js.
  • Regression coverage was added for multiple parenthesis positions and combinations in test/fixtures/win.js, which materially reduces the chance of reintroducing this exact bug.
  • The fix aligns with CMD parsing behavior by using caret escaping, as reflected in the updated expected outputs.
  • The changelog explicitly records the CMD parenthesis correction, improving traceability: commit b4b34c3.

Cons

  • The patch bundle is broader than the GHSA scope, including Dash, Zsh, compose, lint, and test changes. That increases audit complexity for a one-shot security review.
  • The provided sources do not include an end-to-end exploit regression test demonstrating behavior specifically inside a parenthesized cmd.exe block; instead, they validate escaping outputs. That is still useful, but less direct than a parser-context execution test.
  • Because shescape is a shell-escaping library, correctness depends on complete shell grammar coverage. This patch fixes the disclosed parenthesis gap, but the broader risk class remains sensitive to future parser edge cases.

Verdict

Root-cause.

The Windows CMD fix is not a superficial filter or context-specific workaround; it corrects the underlying metacharacter set by adding the omitted grouping operators to the escape regex. The updated Windows fixtures show the library now emits caret-escaped parentheses consistently, which is the necessary behavior to prevent command-group parsing abuse in the scenario described by the advisory. Based on the supplied diffs, this is a technically sound remediation for GHSA-W4HW-QCX7-56PR.

Sources