你以为 npm token 偷了就是 CI 的锅?今天 GitHub 把这件事从根上截住了
npm token 被打包进 GitHub Actions workflow,然后 workflow 被陌生人发起的 PR 触发——你的 npm token 就在那个 CI 环境里被人悄悄 exfiltrate 了。这不是假设,这是 2026 年已经发生过多轮的真实攻击模式。
问题出在哪?CI 默认有 secrets 权限,workflow 触发又门槛极低,而开发者普遍以为「secret scanning 扫到就告警了」,没意识到告警是 push 之后的动作——那个 token 已经跑出去三小时了。
GitHub 2026 年的答案是:在 commit 到达仓库之前直接截住。
2026 年的三个实质升级
一、28 个新检测器,三月一次性上线
2026 年 3 月,GitHub secret scanning 一次性新增 28 个检测器,覆盖 15 家供应商,包括 Vercel、Snowflake、Supabase 等高频中招平台。这不是修修补补,是把过去三年企业里实际流出过 token 的 pattern 全部扫了一遍。
关键变化:其中 39 个检测器直接默认开启 push protection,不再是「先扫描后告警」,而是 push 阶段直接阻断。免费公开仓库同样适用。
新增覆盖的典型代表:
- VolcEngine ARK API Key(七月新增,默认阻止 push)
- Lovable Labs API Key(八月合作,新增 partner 检测)
- Mistral AI API Key、Resend API Key、PostHog OAuth Token
二、Extended Metadata:告诉你这个 token 还能不能用
以前扫到一个 secret,告警只说「发现了」。2026 年八月更新后,部分检测器返回扩展元数据:
- token 持有者是谁
- 创建时间和过期时间
- 关联的项目或组织
这意味着你可以在告警页面直接判断「这是个已经过期的测试 token 不用管」还是「这是一个月前刚创建的 Production token 必须立即轮换」。告警疲劳大幅降低。
三、Workflow 触发权限收紧
2026 年四月,GitHub 给 pull_request_target 默认行为打补丁,同时推进 Workflow Execution Protections 公开预览:管理员可以定义 allow list,控制谁可以触发 workflow,从入口处减少「陌生人发 PR 跑走你的 secrets」的攻击面。
攻击链长什么样
以 2026 年三月发生的 Axios 事件为例(影响 ~100M 周下载量):
- 攻击者通过钓鱼(伪造 Slack workspace + Teams 视频通话)社会工程学拿到 maintainer 的 npm 凭证
- 发布两个含后门的 axios 恶意版本(Windows/macOS/Linux 均有)
- 恶意版本上线三小时后被 Google TAG 和 Microsoft MSTIC 联合确认归属朝鲜 APT 组织 Sapphire Sleet
更隐蔽的是 SANDWORM_MODE 自我传播 worm:通过 typosquatting 冒充常用工具包(claud-code、cloude-code、suport-color),一旦开发者环境被感染,worm 会:
- 窃取 NPM token、GitHub token、环境变量、加密密钥
- 用窃取的凭证继续向更多仓库传播
整个链路里,GitHub Actions workflow 是最薄弱的中间一跳。
三步落地
第一步:确认你的仓库已开启 push protection
仓库 → Security → Secret scanning → 确认 Push protection 状态为 Enabled。新增检测器默认被覆盖,不需要手动配置。
第二步:跑一次 history 扫描
即使当前 push 已被阻止,历史 commit 里可能已有存量 token:
# 在 Security → Secret scanning 页面查看历史告警
# 重点关注 creation date 早于 2026-03 的告警
第三步:给 workflow 加一把锁
# workflow_dispatch 限制 + 环境审批
jobs:
publish:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
#陌生人 PR 永远不触发含 secrets 的 job
environment: production
# 要求人工审批才能访问 environment secrets
加上 OIDC 信任策略,CI 根本不需要持有长期 token——云厂商按需签发临时凭证,workflow 结束即失效。
写在最后
secret scanning 从「事后告警」走到「push 阶段阻断」,是 GitHub 过去一年最实质的安全升级。但工具永远只是最后一道防线——
真正的问题是:你的 CI 凭什么持有可以发布 npm 包的 token?
如果答案是「一直就这么配的」,那这个问题今天该修了。
评论区
登录后可评论。