pull_request_target 与 PR Head 检出:AI Agent 工作流提示注入攻击向量(Vector D)深度解析
【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib
导读
本文基于 anomalib 仓库内agentic-actions-auditor技能库的 Vector D 参考文档,深入剖析一类针对 CI/CD 中 AI Agent(Claude Code Action、Gemini CLI、OpenAI Codex 等)的高危提示注入攻击:当工作流使用pull_request_target触发,并检出 PR 的 head 提交时,攻击者的代码将携带仓库机密(Secrets)进入 AI Agent 的执行上下文。读完本文,你将掌握该向量的完整数据流、两步检测法、漏洞模式示例、误报排除规则与可落地的加固修复方案。
攻击向量概述:可信执行上下文 × 不可信代码
pull_request_target是 GitHub Actions 中一个特殊且高危的触发事件:它运行的是基础分支(base branch)上的工作流定义,而非来自 Fork 的 PR 分支定义。这意味着工作流拥有仓库机密的访问权限,同时却能被任何外部贡献者通过提交 Pull Request 触发。
当工作流在pull_request_target上下文中执行actions/checkout并显式检出 PR 的 head 提交(${{ github.event.pull_request.head.sha }}等)时,就形成了 Vector D 的核心条件:
可信执行上下文(携带 Secrets)+ 攻击者控制的代码(PR head)
AI Agent 在拥有仓库 Secrets 的进程里,读取的是攻击者修改过的文件(代码注释、README、配置文件、测试文件、文档等)。攻击者在这些文件中埋入提示注入载荷,AI 一旦读取并"听从",就会以持有 Secrets 的 Agent 身份执行攻击者指令。
适用 Action:凡是"从工作目录读文件"的 AI 都有风险
该向量的关键前提是:AI Action 会从检出(checked-out)的工作目录读取文件。因此,只要被调用的 AI 工具具备文件系统读取能力,就适用此向量。文档给出的适用性对照如下:
| Action | 适用性 | 说明 |
|---|---|---|
| Claude Code Action | 适用(已确认) | PoC 18 已验证;会读取检出的工作目录文件 |
| Gemini CLI | 适用 | 若配合pull_request_target使用,文件系统读取行为相同 |
| OpenAI Codex | 适用 | 会读取工作目录文件用于代码分析 |
| GitHub AI Inference | 可能 | 较少见,但当提示词指示模型从磁盘读取文件内容时同样适用 |
攻击者将提示注入载荷(prompt injection payload)嵌入代码注释、README 文件、配置文件,或任何 AI 在评审过程中可能读取的文件中——AI 评审的正是这些文件本身,因此注入面天然存在。
触发事件:为什么是 pull_request_target
pull_request_target:工作流从基础分支运行(拥有仓库 Secrets),但由外部 Pull Request 激活。这一"信任"与"不可信输入"的组合正是漏洞根源。- 普通
pull_request:来自 Fork 的 PR不会获得仓库 Secrets,因此从 Secrets 窃取角度看是安全的(虽然代码执行在其他场景下仍是隐患)。
这一点在技能库的 foundations.md 中有完整的触发事件风险对照表:pull_request_target暴露的攻击者可控数据包括 PR 标题、正文、head ref 与 head SHA,且运行于带 Secrets 的基础分支上下文,风险等级最高。
数据流:从攻击者 PR 到 AI 执行上下文
Attacker opens fork PR -> pull_request_target runs workflow from base branch (has secrets) -> actions/checkout with ref: PR head fetches attacker's code to disk -> AI agent reads files from working directory -> Attacker-modified code processed with access to repository secrets这条链路的关键点在foundations.md的三条数据流模型(Path 1 直接表达式插值、Path 2 env 变量中转、Path 3 运行时拉取)之外构成第四种形态:攻击者输入经由"文件系统"这一物理媒介进入 AI 上下文。与 Vector C(CLI 数据拉取)类似,工作流 YAML 本身可能看起来非常"干净"——没有任何${{ github.event.* }}出现在 prompt 字段中,因为恶意内容存在于磁盘文件中,而非事件上下文字符串。
两步检测法:两个条件必须同时成立
检测 Vector D 必须遵循两步走,缺一不可:
第一步:检查on:块中是否存在pull_request_target触发事件
第二步:查找检出 PR head 的 checkout 步骤,命中以下任一模式即触发告警:
actions/checkout(任意版本)带ref:,且取值为以下之一:${{ github.event.pull_request.head.sha }}${{ github.event.pull_request.head.ref }}${{ github.head_ref }}
run:步骤中的git checkout/git fetch命令拉取 PR head 分支或提交
pull_request_target单独出现不是漏洞。没有检出 PR head,AI Agent 只会看到可信的基础分支代码;是"检出"这一步让代码落入攻击者控制。这就是为何该向量在技能库的 SKILL.md 中被标记为 "PR Target + Checkout"(快速检查:pull_request_target触发 + 带指向 PR head 的ref:的 checkout)。
排查位置清单
- 工作流文件顶部的
on:块:查找pull_request_target - 所有 job 中的所有
steps::查找带ref:或with.ref字段的actions/checkout步骤 run:步骤中的git checkout、git fetch、git switch命令,确认是否引用 PR head- 注意:不带
ref:字段的actions/checkout默认检出基础分支,在pull_request_target下是安全的
从技能库的 cross-file-resolution.md 可知,这类 AI Agent 还可能隐藏在被调用的复合动作(composite action)或可复用工作流(reusable workflow)中——审计时应沿uses:引用做一层深度解析,并追踪with:→inputs.*→ prompt 字段的输入映射链路。
为什么危险:Secrets 与攻击者文件的结合
AI Agent 运行时所处的执行上下文携带基础分支 Secrets,可能包括:
- 具备写权限的
GITHUB_TOKEN - 部署密钥(deployment keys)
- API 凭证
- 仓库中配置的任何其他 Secrets
但它处理的却是攻击者修改过的文件。攻击者可以在 AI 大概率会读取的任何文件中埋入提示注入载荷:代码注释、README、配置文件、测试文件、文档。一旦注入成功,AI 将带着这些 Secrets 执行攻击者指令。
foundations.md还补充了一个易被忽略的机制:env:块中的${{ }}表达式在步骤运行之前就被求值,步骤只能看到解析后的字符串值。这意味着即使审计人员未在 prompt 字段中发现表达式,攻击者内容也可能经 env 变量中转进入 AI 上下文(即 Vector A),与本向量叠加放大风险。
漏洞模式示例(来自 PoC 18)
以下 YAML 来自 PoC 18(frankbria/ralph-claude-code),完整展示了两个步骤的配合:
on: pull_request_target: # Step 1: Runs in base branch context types: [opened, synchronize] jobs: claude-review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} # Step 2: Checks out ATTACKER's code - uses: anthropics/claude-code-action@v1 with: prompt: | Please review this pull request and provide feedback # AI reads attacker-modified files from disk with base repo secrets availableStep 1 使工作流在基础分支上下文运行(获得 Secrets);Step 2 把攻击者的代码检出到磁盘;随后 Claude Code Action 以"请评审这个 PR"的善意提示启动,但实际读取的代码、README 与配置文件中都可能是攻击者精心构造的注入指令。
误报排除:五类常见安全场景
为避免安全团队被误报淹没,文档明确列出以下安全场景(最常被误报):
pull_request_target但未检出 PR head:AI 只能看到可信的基础分支代码——这是最常见的误报来源pull_request_target+actions/checkout但无ref:字段:默认检出基础分支,安全- 普通
pull_request触发 + 检出 PR head:Fork 的 PR 不获得 Secrets,无法实现机密窃取(虽然 runner 上的代码执行仍是独立隐患) pull_request_target仅用于打标签、评论或状态检查,且没有在代码上运行 AI Agent:无 AI 处理即无提示注入面pull_request_target的ref:显式指向基础分支(如ref: ${{ github.event.pull_request.base.sha }}):检出的是可信代码
修复与加固建议
结合技能库 action-profiles.md 中各 Action 的安全配置基线,修复方向分为两类:
根治检出问题(直接消除向量 D):
- 优先使用
pull_request触发 + 手动批准后运行,或对来自 Fork 的 PR 不检出 head(默认检出基础分支) - 若必须评审 PR head,先人工审核或使用隔离环境,确保 AI Agent 与仓库 Secrets 不在同一执行上下文
- 在检出后增加内容消毒步骤(去除 HTML 注释、不可见字符、Markdown 图片 alt 文本等隐藏注入载体),这与 Claude Code Action 内置的 prompt 清洗逻辑思路一致
纵深防御(降低注入成功后的影响):
| Action | 推荐加固 |
|---|---|
| Claude Code Action | 用--allowedTools "Bash(npm test:*) Bash(git diff:*)"替代Bash(*);保持show_full_output: false;不使用allowed_non_write_users: "*" |
| OpenAI Codex | sandbox: workspace-write(默认)或read-only;safety-strategy: drop-sudo;allow-users用显式用户列表 |
| Gemini CLI | settings JSON 中配置"sandbox": true;移除--yolo;tools.core中不放run_shell_command(echo)等可扩展命令 |
| 通用 | 最小化permissions:(如contents: read);AI 输出绝不经eval/exec/未加引号的$()消费(Vector G) |
需要特别强调:从本仓库.github/workflows/的实际扫描结果看,现有的auto-approve.yml等文件虽引用了github.event.pull_request.head.sha,但当前仓库工作流中并未发现pull_request_target+ 检出 PR head 的组合,也未发现 AI Action 调用——即本仓库当前不构成 Vector D 的实际利用面,本文所分析的场景适用于"将来或他处引入 AI Agent 工作流"时的防御基线。
结语:把"检出 PR head"当作代码执行边界来审查
Vector D 的本质是信任边界混淆:pull_request_target提供了可信执行上下文(Secrets),而检出 PR head 把不可信代码引入该上下文。审计 CI/CD 中的 AI Agent 集成时,应把"是否检出攻击者控制的代码"视为与"是否执行攻击者脚本"同级的代码执行边界问题。掌握本文的两步检测法与误报排除规则后,即可在引入 Claude Code Action、Gemini CLI 或 OpenAI Codex 等工作流时,快速识别并阻断这一高危注入路径。
【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考