FlawOpen

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

● CVE-2026-102422 · CVSS 8.1 · 高危
安全研究 · FlawOpen

CVE-2026-102422:shell-quote 注释令牌注入

在 shell-quote 1.11.0 之前,注释令牌后跟含有行终止符的字符串时,若将引用后的输出交给 POSIX shell,输出含义可能改变。该问题要求攻击者能影响令牌、应用调用 quote(),并由 shell 执行其输出;请升级到 1.11.0 或更高版本。

💡 通俗易懂的原理解析 (ELI5)

标签上的注释可以隐藏本行后面的内容。如果标签的下一部分含有换行符,注释会提前结束,后面的内容又会显现。这个缺陷使后续令牌能在供 shell 解析的引用输出中造成这种效果。

核心概念与专有名词

shell-quote
用于解析和引用 shell 风格令牌的 JavaScript 软件包;其输出仍是 shell 语法,不是通用安全字符串格式。
注释令牌
表示 shell 注释语法的令牌,其作用可延续到后续文本,直到遇到行终止符。
行终止符
CR、LF、U+2028 或 U+2029 等行边界;shell 可能将其视为注释结束。
CWE-78
未正确中和操作系统命令中的特殊元素。

框架映射

  • 本指南所述弱点的 CWE 参考: CWE-78

根本原因剖析 (Root Cause)

受影响的 quote() 路径会拒绝注释令牌本身包含行终止符的情况,却没有记录注释是否已经输出。因此,后续字符串令牌仍可包含行终止符。当攻击者可影响的令牌传入 quote(),且返回文本由 POSIX shell 执行时,行边界会结束注释,shell 随后把后续文本解析为语法。上游修复会记录注释状态,并拒绝所有后续字符串令牌中的行终止符。这与 CVE-2026-9277 不同:后者的修复针对注释令牌自身的行终止符。维护者评为 High,CVSS 3.1 8.1;Ubuntu 另行给出 CVSS 4.0 9.2 Critical 评估。两者使用不同 CVSS 版本,不能直接互换。

攻击执行流程分解

步骤 1

令牌进入引用函数

应用构造包含注释令牌及后续字符串的序列;攻击者必须能够影响该序列。

步骤 2

函数输出注释语法

在 1.11.0 之前,quote() 会检查注释文本,却不会记住后面还有字符串令牌。

步骤 3

后续令牌含有行边界

CR、LF、U+2028 或 U+2029 可结束 shell 注释。

步骤 4

应用通过 shell 执行输出

文档所述的 shell 解释仅适用于将该输出交给 POSIX shell 的调用方。

步骤 5

升级后拒绝危险序列

1.11.0 会记录注释状态;如果后续字符串含行终止符,就抛出错误。

源代码对比:漏洞与安全实现

有缺陷的代码片段会检查注释令牌中的行终止符,但不会为后续字符串记录状态。上游修改会记录注释已输出,并拒绝包含行终止符的后续字符串。此片段用于说明解析与引用的边界,不是漏洞利用代码或 shell 命令。

源码摘录: quote.js — focused upstream diff hunks

存在漏洞的实现
// commit 6002b2e 之前的 quote.js——注释令牌相关片段
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;
}
加固后的安全修复
// commit 6002b2e 之后的 quote.js——新增校验和注释状态的精确片段
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;
  }
});

工程与系统安全加固清单

参考来源