Skip to Content
SpikesS11 · credential leak

S11 · harden-task-runner-credentials 验证 token 不写盘

目标:验证改用 git credential helper 后,install token 物理上不写入 .git/config(无论 clone / 续期 / fetch / push 哪条路径),跟 POC E1/E2 实测的 https://x-access-token:$TOKEN@github.com/... URL 注入方式形成对比。

日期:2026-05-19 脚本/tmp/spike-token-leak.mjs 结果:✅ 5/5 assertions 通过。

设计

┌───────────────────────────────────────────────────────────────┐ │ spike-token-leak.mjs │ │ │ │ 1. 起本地 bare repo (file:// 协议) 作 clone target │ │ 2. 模拟 run.js clone 流程: │ │ git -c credential.helper=<inline-sh> clone file://upstream│ │ env: INSTALLATION_TOKEN=ghs_fake_secret_NEVER_on_disk │ │ 3. clone 后 git config credential.helper <inline-sh> │ │ 4. cat .git/config · 断言无 token 字面值 │ │ 5. 改 env (新 token) + fetch · 断言 .git/config 仍无 token │ │ │ └───────────────────────────────────────────────────────────────┘

5/5 assertions

#断言结果
1.git/config 不含 ghs_ 前缀的 token 字面值
2.git/config 不含 spike 注入的 TOKEN_LITERAL 字面值
3.git/configcredential.helper 配置(引用 $INSTALLATION_TOKEN env)
4.git/configremote.origin.url 不含 x-access-token:<TOKEN>@ 注入格式
5token 续期路径(改 env 后再 fetch)· .git/config 仍无 token 字面值

实测 .git/config 内容

[core] ... [remote "origin"] url = file:///var/folders/.../upstream.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "main"] remote = origin merge = refs/heads/main [credential] helper = "!sh -c 'echo \"username=x-access-token\"; echo \"password=$INSTALLATION_TOKEN\"'"

关键点

  • [remote "origin"].url 仅含 file:// 路径,无 token 前缀(对比 POC E1/E2 时该行是 https://x-access-token:ghs_xxx@github.com/...
  • [credential].helper 字符串内引用的是变量名 $INSTALLATION_TOKEN,不是变量值——cat .git/config 永远拿不到 token 字面值

对比 POC 实测(PR #12 时)

路径POC(before)本 change(after)
.git/config 含 token 字面值(明文)
续期需要 git remote set-url✗ 是✓ 否 — 仅 process.env.INSTALLATION_TOKEN = newToken
容器 destroy 后磁盘镜像泄漏风险✗ 高✓ 无
printenv 仍可读 token是(接受 · 设计 Non-Goal)
Token blast radius整 install 范围单 repo(由 Plan F 兜底)

仍存在的洞(Non-Goals · 设计明确接受)

  • agent 调 Bash("printenv") 仍能读 $INSTALLATION_TOKEN 字面值
  • agent 调 Bash("cat /proc/self/environ") 仍能读
  • 这两路径都需要攻击者明确指挥 agent(不像 cat .git/config 是 agent 自然行为)
  • 由 Plan F(install token scoped 到单 repo + 2 项 permissions)兜底单 token 滥用损害
  • 由 Plan E 文档化的「网络出口未限制」承认 partial 防护

已知风险 / Limitation

  • 本 spike 在 macOS 本地跑 · 用 file:// 协议绕过 HTTPS 鉴权
  • 实际 Fly Machine 容器内跑时是 HTTPS clone github.com · credential helper 路径走 stdin 喂凭证
  • 后续真跑(任务 §7.3)需要在 Fly 上验证一遍 PR 创建成功 + scoped token + 容器内 .git/config 不含 token