CVE-2026-102422: shell-quote: `quote()` command injection via a line terminator in a token after a `{ comment }` token
shell-quote `quote()` in versions 1.8.4 up to 1.11.0 can be made to run shell commands. A line terminator in a string token that follows a `{ comment }` token ends the shell comment, and the rest of the string runs as shell input. Applications that pass `quote()` output to a shell are affected. Fixed in shell-quote 1.11.0.
Published Oct 6, 2026 · Analysis Oct 25, 2026
What an attacker can do
quote() writes a { comment } token as # plus its text, which comments out the rest of the shell line, including the opening quote of any later string token. If a later string holds a newline, the comment ends there and the text after the newline is parsed as shell commands. The advisory's example, quote(['echo', 'ok', { comment: 'x' }, 'a\nid;#']), produces echo ok #x 'a then id;#'. Passed to sh, bash, dash, ksh or zsh, that runs id.
The flaw is reachable through parse() as well. parse() emits a comment token for a # in the middle of a word, such as the fragment in a URL. Code that builds a command with quote(parse(untrustedCommand).concat(untrustedArg)) therefore has a comment token followed by attacker text. The earlier fix for CVE-2026-9277 rejected line terminators only inside the comment's own text, not in tokens after it.
The attacker needs to control a string that contains a line terminator and that follows a comment token in the same quote() call. That condition makes attack complexity high in the CVSS 3.1 vector. When it holds, they get command execution with the application's privileges.
Who is affected
The npm package shell-quote from 1.8.4 up to, but not including, 1.11.0. You are only exposed if your code calls quote() with a { comment } token followed by an untrusted string, or feeds parse() output plus untrusted strings into quote(), and then hands the result to a POSIX shell.
npm ls shell-quoteThis lists transitive copies too. Then search your code for quote( calls that include parse( output.
shell-quote
- Ecosystem
- npm
- Affected
- >= 1.8.4, < 1.11.0
- Fixed in
- 1.11.0
- Check
npm ls shell-quote
How to fix it
Upgrade to shell-quote 1.11.0:
npm install [email protected]In 1.11.0, quote() throws a TypeError when a string after a { comment } token contains \n, \r, U+2028 or U+2029. Make sure your code handles that exception. For transitive copies, update the parent package or use your package manager's override setting.
Workarounds from the advisory: drop every token after a { comment } token before calling quote(), or reject line terminators in untrusted strings. Do not append other shell text after quote() output that contains a comment, because the comment swallows it.
How to tell if you were hit
Search your code for calls that combine parse() output with other strings in quote(). Check inputs, logs and request data for newline characters (\n, \r, U+2028, U+2029) in strings that end up in shell command lines. Review process-execution logs for unexpected commands started by the service after a quoted call, such as id in the advisory's example. The advisory names no log line.
Original advisory
From the GitHub Advisory Database (CC BY 4.0).
Impact
quote() emits a { comment } token as # followed by its text, which comments out the rest of the shell line, including the opening quote of any later string token. A line terminator in that later string ends the comment, and the rest of the string is parsed as shell input:
quote(['echo', 'ok', { comment: 'x' }, 'a\nid;#']);
// echo ok #x 'a
// id;#'Passed to sh, bash, dash, ksh, or zsh, this runs id.
parse() emits a comment token for a # in the middle of a word (for example http://example.com/#frag), so callers that combine parse() output with another untrusted string, such as quote(parse(untrustedCommand).concat(untrustedArg)), are affected. The fix for CVE-2026-9277 rejected line terminators in the comment's own text, but not in the tokens after it.
Exploitation requires an attacker-controlled string containing a line terminator that follows a { comment } token in the same quote() call.
Patches
Fixed in v1.11.0: quote() throws a TypeError when a string after a { comment } token contains a line terminator (\n, \r, U+2028, or U+2029).
Workarounds
Drop every token after a { comment } token before calling quote(), or reject line terminators in untrusted strings. Separately, do not append other shell text after quote() output that contains a comment, since the comment swallows it.
Credited to euriconicacio, ljharb.
Questions
- Is my app affected if I only call quote() on plain strings?
Not by this flaw. It needs a
{ comment }token followed by a string with a line terminator.parse()creates comment tokens for a mid-word#, so check anyparse()plusquote()combination.- Which shell-quote versions are affected?
1.8.4 up to but not including 1.11.0. Version 1.11.0 fixes it.
- How is this different from CVE-2026-9277?
That fix rejected line terminators in the comment's own text. This one covers line terminators in tokens that come after the comment.
References
How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. The analysis is written by an AI model from the sources listed above and checked by automated rules before it is published. Check versions against the vendor's advisory before you act. Methodology
