文章总结: 文档详细分析了CVE-2026-28292漏洞,其源于simple-git安全插件正则表达式缺失大小写校验,导致攻击者可绕过过滤利用ext协议执行远程代码。文章梳理了该组件的历史漏洞链条,指出黑名单策略的局限性。建议用户立即升级至官方修复版本,或通过白名单过滤及禁用危险协议作为临时缓解措施。 综合评分: 88 文章分类: 漏洞分析,漏洞预警,解决方案
一个字符引发的严重漏洞:CVE-2026-28292 simple-git 远程代码执行分析
原创
CVE-SEC CVE-SEC
CVE-SEC
2026年3月11日 14:00 四川
一个字符引发的严重漏洞:CVE-2026-28292 simple-git 远程代码执行分析
前言
2026 年 3 月 10 日,一个影响 Node.js 生态核心组件的严重漏洞被公开披露。漏洞编号 CVE-2026-28292,评分 9.8,定级 Critical。受影响的组件叫做 simple-git,每周下载量超过 600 万次,被数以万计的 CI/CD 系统、代码平台和 Web 应用所依赖。
而触发这一严重漏洞的根本原因,是一个正则表达式少写了两个字母:/i。
simple-git 是什么
simple-git 是 Node.js 生态中最流行的 Git 操作封装库,由开发者 Steve King(steveukx)开发维护,托管于 GitHub 仓库 steveukx/git-js,通过 npm 发布。
它的设计很直接:让 Node.js 应用能够以简洁的异步 API 调用系统底层的 git 二进制程序,执行克隆、提交、拉取、推送、列出远程等常见 Git 操作。
正因为它做的事足够基础、足够通用,才被大量项目引入,成为 Node.js 生态的基础设施之一。
这不是第一次
要理解 CVE-2026-28292,必须先了解它的历史背景。这是一条从 2022 年延伸至今的补丁绕过链。
2022 年初,CVE-2022-24066 出现。 simple-git 在处理 clone() 时允许使用 Git 的 ext:: 传输协议执行任意命令。
ext:: 是 Git 内置的一种特殊传输协议,格式为 ext://<command>,它会将 command 直接作为 shell 命令执行。这本是为高级用户设计的功能,但一旦被恶意利用,就意味着任意命令执行。Git 自身通过 protocol.ext.allow 配置项将其默认禁用,但 simple-git 未做足够的拦截。
2022 年 10 月,CVE-2022-25912(CVSS 8.1)。 针对上一个漏洞的修复不完整。攻击者仍可向 clone() 方法传递 ext::sh -c touch /tmp/pwn 这样的 URL,并附带 -c protocol.ext.allow=always 参数开启危险协议,完成 RCE。修复版本 3.15.0 发布。
2022 年 12 月,CVE-2022-25860(CVSS 9.8)。 修复再次不彻底。攻击者转向 –upload-pack 和 –receive-pack 参数,对 clone()、pull()、push()、listRemote() 等多个方法同时有效。修复版本 3.16.0 发布。
从 3.16.0 开始,simple-git 引入了专门的安全插件机制 blockUnsafeOperationsPlugin,通过正则表达式在命令执行前扫描参数,拦截危险配置。这个机制设计初衷是好的,但它埋下了新的隐患。
2026 年 3 月,CVE-2026-28292(CVSS 9.8)。 那个安全插件中的正则表达式,对大小写敏感。
漏洞核心:两个字母的差距
简单说清楚技术原理。
simple-git 的安全插件文件 src/plugins/block-unsafe-operations-plugin.ts 使用以下正则表达式拦截危险参数:
/^\s*protocol(.[a-z]+)?.allow/
这个正则的问题在于它只匹配全小写形式。protocol.allow=always、protocol.ext.allow=always 会被拦截,但攻击者只需把参数改成大写或混合大小写:
PROTOCOL.ALLOW=always
PROTOCOL.EXT.ALLOW=always
Protocol.Allow=always
正则无法匹配,安全检查被完全跳过。
而底层的 git 二进制程序在解析 -c 参数时,对配置键名大小写不敏感。这意味着 PROTOCOL.EXT.ALLOW=always 和 protocol.ext.allow=always 对 git 来说完全等价。
过滤层(Node.js 正则)与执行层(git 二进制)之间存在语义不一致,这个缝隙就是漏洞所在。
官方修复只修改了一处,在正则末尾加上 /i 标志:
/^\s*protocol(.[a-z]+)?.allow/i
/i 表示大小写不敏感匹配,所有大写、小写、混合大小写的变体都会被正确拦截。修复代码改动量:两个字符。配套测试用例新增了五种大小写变体的覆盖,确保绕过路径被封堵。
攻击路径
整条利用链如下:
攻击者向目标 Node.js 应用发送包含恶意参数的请求。应用将用户提供的仓库 URL 或配置参数传递给 simple-git 的 clone()、pull() 等方法。simple-git 调用安全插件进行检查,但正则无法匹配大写参数,检查被绕过。参数传递至底层 git 进程。git 接受 PROTOCOL.EXT.ALLOW=always 配置(对大小写不敏感),开启 ext:: 协议支持。git 将 ext:: 格式 URL 中的命令部分作为 shell 命令执行。攻击者以 Node.js 进程所在用户的权限在目标服务器上执行任意命令。
漏洞利用前提:
- 目标应用使用了 simple-git 3.15.0 至 3.32.2 版本
- 应用接收用户可控的输入并传递给 simple-git 的相关方法
- 攻击者能够向目标接口发送请求
满足上述条件时,攻击不需要任何身份认证,攻击复杂度低。
影响范围
受影响版本:simple-git 3.15.0 至 3.32.2。
版本下界是 3.15.0 而非更早版本,原因是安全插件本身是在 3.15.0 引入的,低于 3.15.0 的版本受更早期漏洞影响,属于另一个问题范畴。
修复版本:3.23.0 及以上。
simple-git 的每周下载量约为 600 万至 1200 万次,被大量 CI/CD 工具、自托管代码平台、全栈 Web 应用依赖。典型的高风险场景包括:
CI/CD 系统:如果流水线接收外部贡献者的仓库 URL 并调用 simple-git 执行克隆,攻击者可以通过提交包含恶意 URL 的 PR 在 CI 环境中执行命令,进而窃取构建系统中的密钥、Token,甚至篡改构建产物实施供应链攻击。
代码托管平台:若平台后端使用受影响版本的 simple-git 处理用户的仓库操作请求,攻击者可通过 Web 界面触发 RCE,获取服务器控制权。
普通 Web 应用:任何允许用户提交 Git 仓库地址并由后端执行克隆的应用,均存在被利用的风险。
一个值得关注的模式
CVE-2022-24066 → CVE-2022-25912 → CVE-2022-25860 → CVE-2026-28292。
四个漏洞,同一攻击面,三次绕过。
这种模式在安全历史中并不罕见。每一次修复只针对当时已知的攻击向量,而没有对整个问题域进行完整的安全建模。攻击者对修复逻辑进行观察后,发现过滤条件覆盖不全,选择相邻路径绕过。
对于 simple-git 而言,这个问题的根源在于它选择了黑名单过滤策略:维护一个已知危险模式的列表,并拦截匹配的参数。黑名单的天然局限在于,它只能拦截已知的攻击形态。大小写变体是这一次的绕过手法,未来还可能有其他形式。
白名单策略(只允许明确安全的参数通过)从理论上更为健壮,但需要对业务场景有更深入的了解。对于开源库而言,这个权衡本身也很复杂。
当前修复解决了已知问题,但安全架构层面的讨论仍然值得继续。
如何自查
检查当前项目是否使用了受影响版本:
npm list simple-git
或直接在 package-lock.json 中查找:
grep "simple-git" package-lock.json
若版本在 3.15.0 到 3.32.2 之间,即为受影响。
使用 npm audit 进行自动化扫描:
npm audit
修复方式
官方修复版本为 3.23.0,执行以下命令升级:
npm install simple-git@latest
simple-git 在 3.15.0 至 3.23.0 之间无破坏性 API 变更,升级对大多数项目不会产生副作用。升级后建议运行现有测试套件验证功能正常。
若暂时无法升级,可采取以下临时缓解措施:
在应用层对传入 simple-git 的参数进行白名单过滤,拒绝包含 protocol、allow、ext:: 等关键字的外部输入;在服务器全局 Git 配置中禁用 ext:: 协议:
git config --global protocol.ext.allow never
确保运行 simple-git 的 Node.js 进程以最低权限用户执行,限制 RCE 成功后的横向影响。
检测特征
对于已部署 WAF 或应用层防火墙的环境,可添加以下检测规则,对请求参数中包含以下特征的流量进行告警或阻断(匹配时不区分大小写):
protocol.*\.allow\s*=\s*always
ext::[^\s]+
--upload-pack\s*=
--receive-pack\s*=
若系统日志中出现 Node.js 子进程调用 git 命令且参数包含 ext:: 字符串,需重点关注,可能已发生攻击行为。
总结
CVE-2026-28292 是一个值得被记录的案例。它的危害程度(CVSS 9.8)和触发原因(缺少 /i 标志)之间存在极强的反差,揭示出在安全补丁设计中一个常被忽视的细节:执行层和过滤层对相同输入可能存在不同的解读方式。
对于开发者而言,这个漏洞的启示在于:在对用户输入进行安全过滤时,要充分考虑上下游组件对同一数据的处理语义是否一致。大小写、编码方式、路径规范化,这些看似细枝末节的差异,往往是绕过防护的突破口。
该漏洞已有官方修复,升级成本极低。如果你的 Node.js 项目使用了 simple-git,请立即检查并升级。
漏洞披露时间:2026-03-10 参考资料:
- https://nvd.nist.gov/vuln/detail/CVE-2026-28292
- https://github.com/steveukx/git-js/commit/f7042088aa2dac59e3c49a84d7a2f4b26048a257
- https://www.thehackerwire.com/critical-rce-in-simple-git-cve-2026-28292/
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:CVE-SEC CVE-SEC CVE-SEC《一个字符引发的严重漏洞:CVE-2026-28292 simple-git 远程代码执行分析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论