每次提 PR 都要等缓存命中,但你有没有想过——那个缓存本身可能早就是别人留的后门

每次提 PR 都要等缓存命中才有速度优势,但你有没有想过——那个缓存本身,可能早就是别人留的后门。

GitHub 上个月悄悄改了一条默认规则:Actions 缓存现在对非可信触发器只读。你用 pull_request_target 跑的那些 workflow,以前能往默认分支的缓存里写东西,现在这条路被堵上了。

攻击是怎么实现的

Actions 缓存是跨 workflow 共享的。恶意 workflow 只需要一个能触发运行的机会——比如 pull_request_target、issue_comment,或者一个被注入了脚本的 workflow run——就能往缓存里写一份”毒内容”。真正有权限的 workflow,比如 schedule 或者 push 上的定时发版 job,restore 时会把这份毒内容直接跑起来,secrets 随之泄露。

这个攻击路径最早是安全研究员 Adnan Khan 系统性披露的,之后两年里多起供应链事件都是这么实现的。你以为缓存只是一个加速工具,它实际上是攻击路径的一部分。

现在发生了什么

GitHub 上线了新的缓存策略:非可信触发器(也就是那些没有仓库写权限的人也能触发的事件)拿到的 cache token 现在是只读的。push、schedule、workflow_dispatch 这些可信触发器不受影响,依然是读写的。

具体来说,当触发事件是”非可信”的,同时 workflow 的缓存上下文来自默认分支 SHA,GitHub 就会发一个只读 token。actions/cache 在这种条件下会打印警告然后跳过写入,restore 不受影响。

这对你的 workflow 意味着什么

如果你有 workflow 用 pull_request_target 写缓存,从现在起它不会再写入了。GitHub 建议的修复方式很直接:拆成两个 workflow,一个用可信触发器(如 push)来写缓存,另一个用 pull_request_target 来读。两个 workflow 共享同一份 cache key,读取不设限,写入会走受信路径。

还有一个值得注意的边界:pull_request 事件本身不在只读范围内,因为它的缓存上下文来自 PR 分支而不是默认分支 SHA。真正受限的是 pull_request_target 这类从默认分支 SHA 上下文的触发器。

下一步怎么做

先查一下你的仓库有没有 pull_request_target 配合 actions/cache 的组合。有的话把它当成安全隐患来处理。另外,GitHub 正在做更细粒度的缓存访问控制,允许组织级别限制 cache 读取,这个功能值得关注。

安全这东西,改默认设置比写安全规范有效得多。

评论区

0 条评论

登录后可评论。