gh 登录令牌终于会过期了:泄露几小时就作废

GitHub 10 月 21 日发布 GitHub CLI v2.103.0,gh 登录时可以选「会过期、自动刷新」的 OAuth 令牌(公测)。同一天,LiteLLM 公布了被投毒的经过:起点正是 3 个开发者的 gh OAuth 令牌从日志里泄露。天天让编程 Agent 调 gh 的人,这个开关值得现在就打开。
泄露的令牌从「永久有效」变成「几小时作废」
gh 现在默认拿到的是 gho_ 开头的 OAuth 令牌,没有过期时间。我们这台机器上的 gh 就是这样,gh auth status 只显示前缀和权限范围(gist、read:org、repo),没有任何到期信息。开启新模式后,gh 会同时保存一个短期访问令牌和一个会轮换的刷新令牌,需要时在后台换新,用户不用重新登录。官方原话是,泄露的访问令牌会在几小时内失效,而不是无限期可用。具体有效期官方没有写。
令牌躺进日志的那一刻你不会知道,能控制的只有它在别人手里还能用多久。
为什么现在要关心:LiteLLM 就倒在这一步
LiteLLM 官方的事件说明里写,攻击者从一台暴露在公网的内部 LiteLLM 实例的日志中拿到 3 个开发者的 GitHub CLI OAuth 令牌,其中一个属于组织所有者,于是能关掉分支保护、改写发布流程,最终发布了带木马的 1.107.0。官方还提到,他们观察到 Claude Code 在某些情况下会把 GitHub CLI 令牌写进响应内容,网关开着响应日志就会落盘。编程 Agent 越来越常替人跑 gh,令牌出现在对话和日志里的机会也就多了。
| 默认模式(旧) | expiring 模式(新,公测) | |
|---|---|---|
| 访问令牌寿命 | 不过期,直到手动吊销 | 短期,官方称几小时 |
| 续期 | 不需要 | gh 用刷新令牌自动换新 |
| git over HTTPS | 照常 | 建议 gh auth setup-git,git 2.46 以上 |
| 缓存令牌的脚本 | 能一直用 | 过一阵就失效,需每次 gh auth token |
怎么开,我们试了哪些
gh --version # 需要 2.103.0 及以上
gh config set expiring_credentials enabled # 以后每次登录都要过期令牌
gh auth login --expiring # 或只对这一次登录
gh auth setup-git # 让 git 也用 gh 刷新后的令牌
10 月 22 日我们在 box 上下载了 v2.103.0(发布于 10 月 21 日 23:33 北京时间),确认 gh auth login --help 里已经有 --expiring,expiring_credentials 配置项也能设为 enabled。帮助文本说得很直白:这只是「偏好」,最终发不发过期令牌看服务器和 OAuth 应用的配置,不支持的主机会退回不过期令牌。改完配置后,已有的登录状态没有变化,令牌还是原来那个,要重新登录才会换成新模式。完整的浏览器登录流程我们没有走,未实测刷新行为。
谁该关心
让 Claude Code、Codex 这类 Agent 在本机调 gh 的开发者,以及在网关、代理上记录完整请求响应的团队,最该开。官方提醒:如果某个流程依赖长期不变的令牌,先别对它开启。github.com 和 ghe.com 现在可用,GitHub Enterprise Server 要到 3.23 才支持;官方计划以后把它变成新登录的默认设置。
注意:这是公测功能;「几小时内失效」是 GitHub 的说法,我们没有实测具体时长。LiteLLM 的入侵调查截至其 10 月 21 日 20:30 UTC 的更新仍在进行,进入内部实例的方式尚未确认。
最后
开完这个开关,再顺手查一遍已经泄露的旧令牌:我们的教程 Python 依赖防投毒自查 里有一个扫日志找 token 的脚本,可以直接用。