天下漏洞,尽知其名
HIGH

CVE-2026-102422 shell-quote 命令注入漏洞

影响攻击者可注入并执行任意 shell 命令

AI 研判

shell-quote 的 quote() 函数在输出 { comment } 令牌时,会以 # 开头并注释掉该行后续内容,包括后续字符串令牌的起始引号。若后续字符串中含有换行符(n、r、U+2028、U+2029),注释即被终止,剩余字符串会被当作 shell 输入解析执行。该问题可导致命令注入,属于 CVE-2026-9277 修复不完整的绕过。

影响范围

shell-quote

shell-quote 1.11.0 之前的版本;官方已在 1.11.0 中修复。具体受影响版本范围以官方公告为准。

漏洞详情

漏洞类型为命令注入。成因是 quote() 对 { comment } 令牌之后的字符串未过滤行终止符,导致注释提前结束、后续内容被当作 shell 命令执行。利用方式为构造包含注释令牌和带换行符字符串的输入,例如 quote(['echo','ok',{comment:'x'},'anid;#']) 会在 sh、bash、dash、ksh、zsh 中执行 id。此外 parse() 会把单词中间的 #(如 URL 片段)解析为注释令牌,因此将 parse() 结果与不可信字符串拼接的调用方式同样受影响。

利用条件与风险

利用前提是应用将不可信输入传入 quote(),或采用 quote(parse(不可信命令).concat(不可信参数)) 这类拼接模式。实战中可导致远程命令执行,风险较高。

修复建议

升级到 shell-quote 1.11.0 或更高版本,该版本在 { comment } 令牌之后的字符串含行终止符时抛出 TypeError。临时缓解措施为在调用 quote() 前对输入进行校验,拒绝或转义换行符等行终止符,并避免将 parse() 输出与不可信字符串直接拼接。

原始情报

shell-quote’s `quote()` function 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 (n, r, U+2028, U+2029) in that later string therefore ends the comment, and the rest of the string is parsed as shell input: `quote([‘echo’, ‘ok’, { comment: ‘x’ }, ‘anid;#’])` runs `id` in sh, bash, dash, ksh and zsh. `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. Fixed in 1.11.0: `quote()` throws a `TypeError` when a string after a `{ comment }` token contains a line terminator.