GitHub 11 月 2 日强制关闭公开仓库的 pull_request_target

先说结论

  1. 这不是”建议”,是自动执行。GitHub 的工作流执行保护(Workflow execution protections)已经从 public preview 转正,同时引入一条新默认规则:对还没有适用事件策略的公开仓库,默认禁用 pull_request_target。官方原文写得很明确——2026 年 11 月 2 日会自动对受影响的仓库强制执行。
  2. 私有仓库和内部仓库不受影响。这条默认规则只针对 public repository。所以如果你的仓库是私有的,这篇可以少看一半。
  3. 它防的是”Pwn Request”这类最常被利用的漏洞:pull_request_target 会在拥有 secrets 的上下文里运行,而它又常常被用来跑来自 fork 的代码——两者一叠加,攻击者提一个 PR 就能把你的密钥读走。
  4. 准备动作只有两步:先用官方的 Insights 看哪些 workflow run 会被拦,再决定是”接受这条规则”还是”显式允许 pull_request_target“。别等到 11 月 2 日再查。

为什么 pull_request_target 这么危险

普通的 pull_request 事件在跑来自 fork 的代码时,拿不到你的 secrets,这是设计上的保护。而 pull_request_target 恰恰相反——它刻意运行在目标仓库的上下文里,所以能访问 secrets、能拿到写权限的 token。

官方在公告里把它说成「one of the most commonly exploited vulnerabilities in action workflows」。典型攻击链是:你在 pull_request_target 触发的工作流里 checkout 了 PR 的代码、或者执行了 PR 里带的脚本,于是那段代码就在有 secrets 的环境里跑了起来——这就是 “Pwn Request”。

要强调的是:pull_request_target 本身不是漏洞,它是一个有用但危险的工具。危险来自”在它有权限的上下文里执行不受信任的代码”这个组合。

这次转正带来了三个新能力

新能力 它解决什么
Workflow file targeting 规则可以精确到单个工作流文件,而不是整个仓库。于是「部署工作流锁死、CI 保持开放」这种策略才做得出来
Insights 在强制之前看到这条规则会拦掉哪些 run,也能事后审计影响面。这是迁移前必看的一步
REST API 可以在企业 / 组织 / 仓库三个层级用代码管理规则(含工作流路径条件),几百个仓库就能统一治理,接进现有 IaC 流程

配合原有的 actor / event 规则,现在的保护是按白名单来的:不在允许范围内的执行会被拦下。

危险写法长什么样(对照自查)

同样是 pull_request_target,下面两种写法的风险差了一个量级:

# 危险:在拥有 secrets 的上下文里 checkout 并执行了 PR 的代码
on: pull_request_target
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}   # ← 拉了 fork 的代码
      - run: npm install && npm test                        # ← 在自己的 secrets 环境里跑

# 相对安全:不 checkout PR 代码,只做打标、评论这类不需要执行外部代码的动作
on: pull_request_target
permissions:
  pull-requests: write
  contents: read
jobs:
  label:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/labeler@v5

判断口径很简单:只要在 pull_request_target 的流程里执行了来自 fork 的任何代码(checkout PR ref、跑 PR 里的脚本、装 PR 里的依赖),就已经站在漏洞上了。

受影响的人该做什么(按顺序)

  1. 先看 Insights:它会告诉你哪些 workflow run 在强制开始后会失败。不要凭感觉判断自己受不受影响。
  2. 然后二选一:
    • 接受规则:如果你的公开仓库确实不需要 pull_request_target,什么都不用做,等它生效即可(顺带白拿一层保护)。
    • 显式允许:如果工作流还依赖这个触发器,就在适用的 Actions 事件策略里明确允许。
  3. 用 REST API 把它变成策略即代码:一次写完,推到所有仓库,比在 UI 里一个个点可靠得多。
  4. 顺手做一次凭证审计:就算规则保住了,也值得查一遍 pull_request_target 触发的 workflow 里有没有:直接 checkout PR 代码、run: 里执行 PR 提供的脚本、把 secrets 传给第三方 action。
  5. 把粒度收紧到 workflow 级别:既然支持单文件规则了,就不要再”整个仓库一刀切”——部署类工作流严格、CI 类适当放开,这才是这次新能力真正的用法。

三个容易搞错的点

  • 「默认规则」不等于「所有仓库都拦」:官方说明里限定的是”还没有适用事件策略”的公开仓库。已经有策略的仓库按自己的策略走。
  • 「自动强制」有明确时间点:2026 年 11 月 2 日。离现在只有六周,企业环境走审批流程的话现在就该动。
  • 私有仓库不受这条默认规则影响,但不代表私有仓库就安全——如果你自己显式配了 pull_request_target,风险还在。

这次没核实的

  • 我没有 GitHub Enterprise 环境可以实际验证这三项能力的 UI 与 API 细节,本文的事实全部来自官方公告原文。
  • REST API 的具体端点与权限范围公告里没有展开,要落地请以官方 API 文档为准。
  • “受影响仓库”的具体判定逻辑(什么算”还没有适用事件策略”)公告给的边界比较粗,如果你的仓库历史上配过事件策略又改过,建议用 Insights 实测确认。

参考来源

评论区

0 条评论

登录后可评论。

橘子汽水 913 阅读