教程2026-11-03 · 智涌AI

GitHub pull_request_target 自查:12 月默认拦截前修工作流

GitHub pull_request_target 自查头图:终端用 rg 扫描工作流,标注 11 月预演与 12 月 2 日默认拦截

GitHub 在 2026-11-02 的 Changelog 里把公开仓库 pull_request_target 的默认拦截推迟到 2026-12-02,并安排了 11 月 9 日、16 日各两小时的预演拦截。站内已有这条快讯。下面按官方 Changelog、Actions 策略文档和「Securely using pull_request_target」整理一份自查清单:先扫仓库有没有这个触发器,再决定是改成 pull_request、保持默认拦截,还是在策略里精确放行。本站仓库 zhiyong-ai-site 在 2026-11-03 北京时间用 rg 扫过,没有 .github/workflows,也没有 pull_request_target。

先把时间线钉死:预演两次,12/2 才永久拦

Changelog 写明:原计划 11 月 2 日生效,现推迟到 2026-12-02。正式生效前有两次 brownout(预演拦截),每次两小时:

窗口UTC北京时间行为
第一次预演2026-11-09 16:00–18:0011-10 00:00–02:00被默认规则拦住的 pull_request_target 运行会失败并带错误注释,工作流不执行
第二次预演2026-11-16 16:00–18:0011-17 00:00–02:00同上
正式生效2026-12-02 起同日起公开仓库默认拦截,除非适用的 Actions 事件策略显式允许

影响范围是 GitHub Free、Team、Enterprise Cloud 上的公开仓库;私有、内部仓库和 Enterprise Server 不受影响。预演窗口结束后,默认规则会回到 evaluate(评估)模式:工作流仍可跑,但 Insights 里能看到「正式生效后会被拦」的记录。

11 月 9 日第一次预演前就把列表扫完——等窗口里 CI 集体变红,再临时改策略就晚了。

风险点:有密钥的上下文里执行了 fork 代码

官方文档对比了两种事件:

危险出现在作者主动改掉默认:把 actions/checkout 指到 github.event.pull_request.head.sha(或 refs/pull/…/merge、fork 的 repository:),紧接着 make test、npm install、npm run build 等会执行检出目录里的脚本、依赖和配置。这就是 Security Lab 说的 pwn request:攻击者只要从 fork 开一个 PR,就能在带密钥的上下文里跑自己的构建链。文档还提醒:同类风险也会出现在 workflow_run / issue_comment 等「有密钥」事件里,只要去下载并执行了不可信代码或工件。

自查第 1 步:把触发器和工作流文件扫出来

在本机对每个要管的公开仓库(或组织镜像)跑只读扫描。下面命令不改任何配置,只列文件:

# 在仓库根目录:列出含 pull_request_target 的工作流
rg -n --glob '.github/workflows/*.{yml,yaml}' 'pull_request_target'

# 同时标出「检出 PR head / merge」的常见写法(高危组合信号)
rg -n --glob '.github/workflows/*.{yml,yaml}' \
  'pull_request\.head\.sha|refs/pull/.*/(head|merge)|allow-unsafe-pr-checkout'

# 有 gh 且已登录时:列组织下公开仓库(按需改 ORG)
gh repo list ORG --visibility public --limit 200 --json nameWithOwner \
  --jq '.[].nameWithOwner'

2026-11-03 对本站 /workspace/ai-site 执行上述 rg:仓库没有 .github/ 目录,匹配数为 0。你自己的组织请把每个命中文件记进表:路径、是否 checkout 了 PR head、后续步骤有没有 npm/make/pip/cargo 等会执行检出树的命令、用到了哪些 Secrets。

自查第 2 步:先看 Policy insights,再选三种处置之一

Changelog 建议在第一次预演前打开 Actions → Policies 下的 Policy insights,看评估模式里「会被默认规则拦住」的运行。对每个命中工作流,官方给出的决策顺序是:

判断做法适合谁
其实不需要密钥 / 写权限把 on: 改成 pull_request(或拆成「不可信侧跑测试 + 可信侧用 workflow_run 读工件」)大多数公开仓库 CI
不需要这个触发器删掉或注释掉 pull_request_target,保持 GitHub 默认拦截历史遗留、已无人维护的 YAML
必须保留(贴标签、分诊、已认证检查等)在仓库 / 组织 / 企业的 Actions 事件策略里显式允许 pull_request_target,并尽量按工作流文件路径缩小范围开源维护机器人、需要写评论的自动化

创建策略的路径(文档「Control workflow execution」):仓库或组织 → Settings → Actions → Policies → 新建策略 → 选择强制状态(Evaluate 可先观察)→ 配置 Restrict events,把需要的事件放进允许列表。企业级在 Policies → Actions → Policies。策略可以叠多层;已有显式事件策略时,不会被「默认拦截」那条替换掉——以你配置的为准。

# 示例:只保留贴标签,不再检出 PR head(示意,按仓库改名)
# .github/workflows/label-fork-prs.yml
on:
  pull_request_target:
    types: [opened, reopened, synchronize]
permissions:
  pull-requests: write
  contents: read
jobs:
  label:
    runs-on: ubuntu-latest
    steps:
      - name: Add label
        # 只用 github.event 元数据;不要 actions/checkout 到 head.sha
        run: echo "label via API / softprops 等;勿执行 fork 树"

若确认必须检出 fork 代码且只当数据读、绝不执行:官方要求先通过「是否可用 pull_request」「检出代码会不会被执行」两道题;仍要越过 actions/checkout 保护时才设置 allow-unsafe-pr-checkout: true。文档写明该输入名字故意刺眼,方便代码审查和静态扫描发现。它只覆盖 fork PR 的 checkout 路径;用 git fetch、gh pr checkout 或下载其它工作流工件再执行,不在这个保护范围内。

常见坑

完成标准

最后

今天先对公开仓库跑一遍 rg,把命中工作流按上表三选一处理,并在 11 月 9 日预演前打开 Policy insights 对过名单。四条完成标准打完勾,12 月默认拦截就是一次排期发布,而不是凌晨的 CI 事故。

关注公众号「智涌AI速递」

每天的 AI 快讯、实用教程和 AI项目实测,也会同步发到微信公众号。在微信里搜索「智涌AI速递」就能关注;不用微信的话,可以用 RSS 订阅本站。