flawopen.com/Teardowns/cve-2026-102422-shell-quote-comment-line-terminator-injection
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.
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
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.
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.
A later token contains a line boundary
A CR, LF, U+2028, or U+2029 in that later string can terminate the shell comment.
Caller invokes the quoted output in a shell
Only callers that pass this output to a POSIX shell encounter the documented shell interpretation boundary.
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
// 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;
}
// 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
- ✓Upgrade direct and transitive
shell-quotedependencies to 1.11.0 or later; verify the resolved version in the lockfile and deployed artifact. - ✓Do not treat
quote()as safe for arbitrary contexts or as a substitute for avoiding shell invocation. - ✓Where practical, invoke a fixed executable with an argument array and
shell: false; validate each argument for the target program. - ✓If shell interpretation is unavoidable, keep the command structure fixed and reject comment-token sequences followed by line terminators before invocation.
- ✓Add regression tests for CR, LF, U+2028, and U+2029 in later string tokens, including tokens produced by
parse(). - ✓Review call sites that feed attacker-influenced tokens to
quote()and then execute the result; package use alone does not establish exploitability. - ✓Do not infer Ubuntu package fix status from the upstream npm release; check the distribution advisory for the exact release package.