关于 gha-security-review
gha-security-review 是用于检查 GitHub Actions 工作流、Action 及相关脚本中外部攻击者可利用漏洞的技能。它要求基于证据追踪攻击路径并给出具体场景,不报告理论性或低置信度问题。
主要功能
- 01威胁模型限定为外部攻击者
- 02检查八类工作流漏洞
- 03要求追踪并描述攻击场景
- 04仅报告高或中置信度问题
- 05提供安全模式与验证步骤
适用场景
- 01检查 pull_request_target 工作流是否执行不可信分支代码
- 02追踪外部触发工作流中的表达式注入
- 03评估密钥、权限、第三方 Action 与运行器
- 04为工作流文件和脚本编写基于证据的发现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill gha-security-review安装后在 Claude Code 中输入/gha-security-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
UPSTREAM-LICENSE.txtUPSTREAM-NOTICE.mdreferences/credential-escalation.mdexpression-injection.mdcomment-triggered-commands.mdpermissions-and-secrets.mdpwn-request.mdai-prompt-injection-via-ci.mdreal-world-attacks.mdrunner-infrastructure.mdsupply-chain.md详细介绍
内置的上游支持
支持文件位于相对于技能目录的路径中。有关其固定来源、许可证、哈希值和导入变更,请参阅 UPSTREAM-NOTICE.md。
GitHub Actions 安全审查
查找 GitHub Actions 工作流中可被利用的漏洞。每项发现都必须包含具体的利用场景——如果无法追踪攻击路径,就不要将其报告为已确认的问题。仅使用无害的 PoC 示意;未经明确授权,不要触发工作流、窃取密钥或发布攻击者内容。
此技能总结了真实 GitHub Actions 漏洞利用中的攻击模式,而非泛泛的 CI/CD 理论。
适用场景
- 你正在审查 GitHub Actions 工作流中可被利用的安全问题。
- 任务要求追踪从外部攻击者到工作流执行或密钥泄露的具体攻击路径。
- 你需要审查工作流文件、复合操作或与工作流相关的脚本,并且只报告有证据支持的发现。
范围
审查提供的工作流(文件、差异或仓库)。根据需要研究代码库,以便在报告前追踪完整的攻击路径。
要审查的文件
.github/workflows/*.yml— 所有工作流定义action.yml/action.yaml— 仓库中的复合操作.github/actions/*/action.yml— 本地可复用操作- 工作流加载的配置文件:
CLAUDE.md、AGENTS.md、Makefile、.github/下的 Shell 脚本
范围之外
- 其他仓库中的工作流(仅注明依赖关系)
- GitHub App 安装权限(如相关,请注明)
威胁模型
仅报告可被外部攻击者利用的漏洞——即没有仓库写入权限的人。攻击者可以从 Fork 创建 PR、创建 Issue 并发表评论。他们无法推送到分支、触发 workflow_dispatch 或触发手动工作流。
不要标记需要写入权限才能利用的漏洞:
workflow_dispatch输入注入——需要写入权限才能触发- 仅在受保护分支上运行的
push工作流中的表达式注入 - 所有调用方均为内部调用方时的
workflow_call输入注入 - 仅在
workflow_dispatch/schedule工作流中使用的密钥
置信度
仅报告置信度为高和中的发现。不要报告理论性问题。
| 置信度 | 标准 | 操作 |
|---|---|---|
| 高 | 已追踪完整攻击路径,确认可利用 | 附上利用场景和修复方案进行报告 |
| 中 | 攻击路径已部分确认,存在不确定环节 | 报告并标注为需要验证 |
| 低 | 属于理论性问题或已在其他位置缓解 | 不要报告 |
对于每项高置信度发现,提供以下全部五项内容:
- 入口点 — 攻击者如何进入?(Fork PR、Issue 评论、分支名称等)
- 载荷 — 攻击者发送什么?(实际代码/YAML/输入)
- 执行机制 — 载荷如何运行?(表达式展开、检出后运行脚本等)
- 影响 — 攻击者能获得什么?(窃取令牌、执行代码、仓库写入权限)
- PoC 示意 — 攻击者会执行哪些具体步骤
如果无法构造全部五项内容,则报告为中置信度(需要验证)。
步骤 1:对触发条件分类并加载参考资料
对于每个工作流,识别触发条件并加载相应的参考资料:
| 触发条件/模式 | 加载参考资料 |
|---|---|
pull_request_target | references/pwn-request.md |
带命令解析的 issue_comment | references/comment-triggered-commands.md |
run: 块中的 ${{ }} | references/expression-injection.md |
| PAT/部署密钥/高权限凭据 | references/credential-escalation.md |
| 检出 PR 代码并加载配置文件 | references/ai-prompt-injection-via-ci.md |
| 第三方 actions(尤其是未固定版本的) | references/supply-chain.md |
permissions: 块或使用机密 | references/permissions-and-secrets.md |
| 自托管运行器、缓存/构件的使用 | references/runner-infrastructure.md |
| 任何已确认的问题 | references/real-world-attacks.md |
有选择地加载参考资料——只加载与发现的触发条件相关的内容。
步骤 2:检查漏洞类型
检查 1:Pwn Request
工作流是否使用 pull_request_target 并检出 fork 代码?
- 查找
actions/checkout中指向 PR head 的ref: - 查找可能来自 fork 的本地 actions(
./.github/actions/) - 检查是否有任何
run:步骤执行检出的 PR 中的代码
检查 2:表达式注入
可由外部触发的工作流是否在 run: 块中使用 ${{ }} 表达式?
- 列出每个
run:步骤中的所有${{ }}表达式 - 确认值是否由攻击者控制(PR 标题、分支名称、评论正文——而非数字 ID、SHA 或仓库名称)
- 确认表达式位于
run:块中,而非if:、with:或作业级env:
检查 3:未授权命令执行
由 issue_comment 触发的工作流是否在未授权的情况下执行命令?
- 是否检查了
author_association? - 任意 GitHub 用户都能触发该命令吗?
- 命令处理程序是否也使用了可注入的表达式?
检查 4:凭据提升
不受信任的代码能否访问高权限凭据(PAT、部署密钥)?
- 每个机密的影响范围有多大?
- 工作流遭到入侵后,攻击者能否窃取长期令牌?
检查 5:配置文件投毒
工作流是否加载了 PR 提供的配置?
- AI Agent 指令:
CLAUDE.md、AGENTS.md、.cursorrules - 构建配置:
Makefile、shell 脚本
检查 6:供应链
第三方 actions 是否经过安全固定?
检查 7:权限和机密
工作流权限是否遵循最小化原则?机密是否经过妥善限定?
检查 8:运行器基础设施
自托管运行器、缓存或构件是否安全使用?
安全模式(不要标记)
报告之前,先检查该模式是否实际上安全:
| 模式 | 安全原因 |
|---|---|
使用 pull_request_target,但不检出 fork 代码 | 仍需检查元数据注入、actions、构件和其他不受信任的输入 |
run: 中的 ${{ github.event.pull_request.number }} | 仅为数字,不可注入 |
${{ github.repository }}/github.repository_owner | 仓库所有者控制此值 |
${{ secrets.* }} | 不是表达式注入途径 |
if: 条件中的 ${{ }} | 由 Actions 运行时求值,而非 shell |
with: 输入中的 ${{ }} | 此处不会自动进行 shell 插值;追踪 action 如何使用该输入 |
| 固定到完整 SHA 的 actions | 固定该 action 源码;但不能证明代码安全,也不能保证运行时下载内容不可变 |
pull_request 触发器(而非 _target) | fork 的令牌/机密通常受到限制;同仓库 PR、设置和自托管基础设施仍需审查 |
受保护分支上的 workflow_dispatch/schedule/push 中的任何表达式 | 需要写入权限——不属于威胁模型 |
关键区别: ${{ }} 在 run: 块中存在危险(shell 展开);if:、with: 和 env: 不会产生这种直接替换入口。但下游的 eval、通过 shell 拼接命令、JavaScript 执行以及不安全的 action 输入,仍可能重新引入注入风险。
第 3 步:报告前进行验证
纳入任何发现之前,请阅读实际工作流 YAML 并追踪完整攻击路径:
- 阅读完整工作流——不要只依赖 grep 输出
- 追踪触发条件——确认事件,并检查控制执行的
if:条件 - 追踪表达式/检出操作——确认它位于
run:块中,或确实引用了 fork 代码 - 确认攻击者可控——验证该值对应外部攻击者可以设置的内容
- 检查现有缓解措施——环境变量封装、author_association 检查、受限权限、SHA 固定
如果攻击路径的任一环节不成立,请标记为 MEDIUM(需要验证)或删除该发现。
如果检查没有发现任何问题,请报告零项发现。不要凭空捏造问题。
第 4 步:报告发现
## GitHub Actions Security Review
### Findings
#### [GHA-001] [Title] (Severity: Critical/High/Medium)
- **Workflow**: `.github/workflows/release.yml:15`
- **Trigger**: `pull_request_target`
- **Confidence**: HIGH — confirmed through attack path tracing
- **Exploitation Scenario**:
1. [Step-by-step attack]
- **Impact**: [What attacker gains]
- **Fix**: [Code that fixes the issue]
### Needs Verification
[MEDIUM confidence items with explanation of what to verify]
### Reviewed and Cleared
[Workflows reviewed and confirmed safe]
如果没有发现:"在审查范围和既定假设内,未发现可利用的漏洞。" 列出未读取的工作流、无法访问的设置和未经验证的运行时链接;不要断言所有工作流都安全。
局限性
- 仅当任务明确符合上述范围时才使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必需的输入、权限、安全边界或成功标准,请停止并请求澄清。