自包含实验室,证明 GitLab npm 包注册表路径遍历(CVE-2026-10053)并展示其已修复,使用确定性的磁盘上 oracle(判定依据)——而非 HTTP 状态。
已证明与未证明的内容。 本实验室证明在易受攻击的 GitLab 上,可以以
git操作系统用户身份进行经过身份验证的任意文件写入,并且已修补版本会阻止该操作。它不是独立的远程代码执行 PoC——参见范围。请勿将其引用为 RCE。
python3、git、curl。./run.sh # up + provision + exploit + verify BOTH; exits 0 iff vuln writes AND patched blocks
预期结果:
================ CVE-2026-10053 verification ================
INSTANCE EXPECT RESULT STATUS
gitlab-vuln (19.2.1) written written PASS
gitlab-patched (19.2.2) blocked blocked PASS
------------------------------------------------------------
PROVEN: authenticated arbitrary file write as git on 19.2.1.
NOT a standalone RCE — see README.md 'Scope' and ./run.sh rce-gate.
============================================================
其他子命令:
./run.sh up # just start + wait until healthy
./run.sh rce-gate # honest exec-bit-gate demo (below)
./run.sh down # docker compose down -v
易受攻击和已修补的服务器都会以 HTTP 200 {"status":"processing"} 应答恶意发布——文件稍后由 finalize worker 写入。因此 HTTP 状态不是 oracle。exploit/poc.py --verify-docker <container> 改为在容器内部轮询被遍历路径上的受控文件,并比较其 SHA-1:
/var/tmp/CVE_2026_10053_PROOF-1.0.0.tgz(属主 git:git,内容为我们的字节)→ 退出码 0。Gitlab::PathTraversal::PathTraversalAttackError: Invalid path → 退出码 2。exploit 本身仅仅是经过身份验证的 PUT …/packages/npm/:pkg 请求;路径遍历完全存在于 JSON 请求体 name 中(file_name = "#{name}-#{version}.tgz",仅做了空白检查)。docker exec 调用属于验证和设置,从来不是攻击者的能力范围。
git 可写路径。文件权限为 0644。-<semver>.tgz 结尾(内核拒绝 NUL,换行符不会截断),因此无法覆盖任何名称精确匹配的目标(secrets.yml、authorized_keys、.rb 文件、gitaly 二进制文件)。唯一与文件名无关的执行器 custom_hooks/<hook>.d/ 可运行任意文件名,但前提是该文件可执行——而此写入是 0644。覆盖已有的 0755 文件也没有帮助:store 会替换 inode,将其重置为 0644。因此 RCE 需要单独的可执行位 / 执行原语,本 PoC 并未提供。./run.sh rce-gate 诚实地演示了这一点:它通过路径遍历植入一个 pre-receive.d 钩子,执行 push,并展示 0644 钩子不会执行。./rce_gate_demo.sh --illustrate-gate 另外通过 docker exec chmod 设置 +x(一种带外 docker-root 操作,不是攻击者能力),纯粹为了展示 gitaly 会运行它——强调缺失的关键条件正是可执行位。
完整分析见 ANALYSIS.md。简言之:app/uploaders/gitlab_uploader.rb 仅在 before :cache 时验证存储路径;在 before :store 时,由模型派生的 file_name(攻击者可控、未经校验)被原样写入。修复方案新增了 before :store, :protect_from_path_traversal!。
docker-compose.yml vuln (19.2.1) + patched (19.2.2) GitLab CE
run.sh one-command harness with deterministic file oracle + PASS/FAIL
provision.rb lab setup: mint root PAT + create project (NOT part of the exploit)
exploit/poc.py the PoC sender + --verify-docker oracle
rce_gate_demo.sh honest exec-bit-gate demonstration
| 漏洞 | npm 包注册表中的 CWE-22 路径遍历(TOCTOU:检查在 before :cache 运行,而非 before :store) |
| CVSS | 8.5 高危 — AV:N/AC:H/PR:L/UI:N/S:C:C:H/I:H/A:H |
| 受影响版本 | GitLab CE/EE 18.8 → <19.0.6, 19.1 → <19.1.4, 19.2 → <19.2.2 |
| 已修复 | 19.0.6 / 19.1.4 / 19.2.2 — 提交 435cf863 “在 store 前重新验证上传路径遍历” |