FlawOpen

flawopen.com/Teardowns/cve-2026-102422-shell-quote-comment-line-terminator-injection

● CVE-2026-102422 · CVSS 8.1 · High
FlawOpen Security Research

CVE-2026-102422: shell-quote comment-token injection

Before shell-quote 1.11.0, a comment token followed by a string containing a line terminator could make quoted output change meaning when passed to a POSIX shell. The vulnerable condition requires attacker-influenced tokens, a call to quote(), and execution of its output by a shell; upgrade to 1.11.0 or later.

💡 Plain English Explainer (ELI5)

A comment on a shipping label can hide everything after it on that line. If the next part of the label contains a line break, the hidden text ends early and the rest becomes visible again. This bug let a later token do that in shell-quoted output.

Core Concepts & Subsystem Terms

shell-quote
A JavaScript package that parses and quotes shell-style tokens; quoting output is still intended for shell syntax, not a universal safe-string format.
Comment token
A token representing shell comment syntax. Its effect can extend across following text until a line terminator.
Line terminator
A line boundary such as CR, LF, U+2028, or U+2029; a shell can treat it as the end of a comment.
CWE-78
Improper neutralization of special elements used in an OS command.

Framework mappings

  • CWE reference for the weakness described in this guide: CWE-78

Root Cause Analysis

The affected quote() path rejected line terminators inside the comment token, but did not track that a comment had already been emitted. A later string token could therefore contain a line terminator. In the specific case where attacker-influenced tokens reach quote() and the returned text is run by a POSIX shell, the line boundary ends the comment and the shell parses following text as syntax. The upstream fix records comment state and rejects line terminators in every later string token. This is distinct from CVE-2026-9277, whose fix rejected line terminators inside the comment token itself. Maintainers rate this High, CVSS 3.1 8.1; Ubuntu publishes a separate CVSS v4.0 9.2 Critical assessment. These scores use different versions and are not interchangeable.

Step-by-Step Attack Flow

Step 1

Token input reaches the quoting function

An application constructs tokens that include a comment token and a later string; attacker influence over that sequence is required.

Step 2

The function emits comment syntax

Before 1.11.0, quote() checked the comment text itself but did not remember that later string tokens followed it.

Step 3

A later token contains a line boundary

A CR, LF, U+2028, or U+2029 in that later string can terminate the shell comment.

Step 4

Caller invokes the quoted output in a shell

Only callers that pass this output to a POSIX shell encounter the documented shell interpretation boundary.

Step 5

Upgrade rejects the unsafe sequence

Version 1.11.0 tracks whether a comment was emitted and throws when a subsequent string contains a line terminator.

Source Code: Flaw vs. Secure Implementation

The vulnerable excerpt checks line terminators in the comment token but omits state for following string tokens. The upstream change records that a comment was emitted and rejects a later string containing a line terminator. This excerpt illustrates the parser/quoting boundary and is not an exploit or shell command.

Source excerpt: quote.js — focused upstream diff hunks

UNPATCHED FLAW
// quote.js before commit 6002b2e — focused comment-token hunk
if ('comment' in s && typeof s.comment === 'string') {
  if (LINE_TERMINATORS.test(s.comment)) {
    throw new TypeError('`comment` must not contain line terminators');
  }
  return '#' + s.comment;
}
HARDENED SECURE PATCH
// quote.js after commit 6002b2e — exact added guard and comment-state hunk
var sawComment = false;
return xs.map(function (s) {
  if (sawComment && typeof s === 'string' && LINE_TERMINATORS.test(s)) {
    throw new TypeError('a token after a `comment` must not contain line terminators');
  }
  if ('comment' in s && typeof s.comment === 'string') {
    if (LINE_TERMINATORS.test(s.comment)) {
      throw new TypeError('`comment` must not contain line terminators');
    }
    sawComment = true;
    return '#' + s.comment;
  }
});

Engineering & System Hardening Checklist

Sources