github-actions-hardening
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGitHub Actions Hardening
GitHub Actions 安全强化
A focused security reviewer for GitHub Actions workflows. It reasons about the Actions-specific
threat model — where trust boundaries live in trigger types, token scopes, and string
interpolation — rather than the application-code vulnerabilities a general security scanner looks
for. Most workflow risks are invisible to language linters because the dangerous code is the YAML
itself and the way GitHub expands expressions into a shell before your script runs.
${{ }}一款专注于GitHub Actions工作流的安全审查工具。它针对Actions特有的
威胁模型进行分析——包括触发器类型、令牌范围和字符串插值中的信任边界——而非通用安全扫描器关注的应用代码漏洞。大多数工作流风险无法被语言检查工具发现,因为危险代码存在于YAML本身,以及GitHub在脚本运行前将表达式扩展为shell命令的方式中。
${{ }}When to Use This Skill
适用场景
Use this skill when the request involves:
- Reviewing, auditing, or hardening any file under
.github/workflows/ - Authoring a new workflow and wanting it secure by default
- A workflow that uses ,
pull_request_target, orworkflow_runtriggersissue_comment - Questions about permissions or the
GITHUB_TOKENkeypermissions: - Pinning actions to commit SHAs vs tags vs branches
- Handling untrusted input (issue titles, PR bodies, branch names, commit messages) in steps
run: - OIDC / cloud authentication from Actions, or secret handling in CI
- Self-hosted runners on public repositories
- Any request like "is this workflow safe?", "secure my CI", or "review this GitHub Action"
当请求涉及以下内容时,可使用此技能:
- 审查、审计或强化下的任何文件
.github/workflows/ - 编写新工作流并希望默认具备安全性
- 使用、
pull_request_target或workflow_run触发器的工作流issue_comment - 关于权限或
GITHUB_TOKEN关键字的问题permissions: - 将Actions固定到提交SHA、标签或分支的对比
- 在步骤中处理不可信输入(议题标题、PR内容、分支名称、提交信息)
run: - 从Actions进行OIDC/云身份验证,或CI中的密钥处理
- 公共仓库中的自托管运行器
- 任何诸如“这个工作流安全吗?”“加固我的CI”或“审查这个GitHub Action”的请求
The Core Insight
核心要点
In a workflow, is expanded by the runner into the script before the shell
executes it. So a step like:
${{ <expr> }}yaml
- run: echo "Title: ${{ github.event.issue.title }}"is not passing a variable — it is pasting attacker-controlled text directly into your shell
command. An issue titled is concatenated into the script and executed.
This single mechanism is the most common real-world Actions vulnerability, and models routinely
generate it. Treat every
that contains data an outside contributor can influence as a code-injection sink.
"; <attacker-command> #${{ }}在工作流中,会被运行器在shell执行脚本之前扩展到脚本中。因此,如下步骤:
${{ <expr> }}yaml
- run: echo "Title: ${{ github.event.issue.title }}"并非传递变量——而是将攻击者可控的文本直接粘贴到你的shell命令中。如果议题标题为,则会被拼接到脚本中并执行。这是现实中最常见的Actions漏洞,且模型经常会生成此类漏洞。请将所有包含外部贡献者可影响数据的视为代码注入风险点。
"; <attacker-command> #${{ }}Execution Workflow
执行流程
Follow these steps in order for every workflow reviewed.
请按以下顺序步骤审查每个工作流。
Step 1 — Map the Triggers and Trust Level
步骤1 — 映射触发器与信任级别
Read every trigger and classify the workflow's privilege:
on:- ,
push(from same repo) → runs with the contributor's own trustpull_request - from a fork → runs with a read-only token, no secrets (safe by design)
pull_request - ,
pull_request_target,workflow_run,issue_comment→ run in the context of the base repository with a read/write token and full access to secrets, but can be triggered by outside contributors. These are the dangerous triggers.issues
Read for the full trust matrix.
references/triggers-and-privilege.md读取每个触发器并分类工作流的权限:
on:- 、
push(来自同一仓库)→ 使用贡献者自身的信任权限运行pull_request - 来自fork仓库的→ 使用只读令牌运行,无密钥访问(设计上安全)
pull_request - 、
pull_request_target、workflow_run、issue_comment→ 在基础仓库的上下文中运行,拥有读写令牌和完整密钥访问权限,但可能被外部贡献者触发。这些是危险的触发器。issues
请阅读获取完整的信任矩阵。
references/triggers-and-privilege.mdStep 2 — Hunt for Script Injection
步骤2 — 排查脚本注入
For every block, every in , and every input to a custom
action, list the expressions and check whether any resolve to attacker-controllable data.
High-risk contexts include:
run:script:actions/github-script${{ }}- ,
github.event.issue.titlegithub.event.issue.body - ,
github.event.pull_request.title,github.event.pull_request.body,.head.ref.head.label - ,
github.event.comment.bodygithub.event.review.body - ,
github.event.pages.*.page_name,github.event.commits.*.messagegithub.event.head_commit.* - and any
github.head_reffield a fork author can setgithub.event.*
Read for the complete sink list and the safe-pattern fixes.
references/injection.md对于每个块、中的每个以及自定义Action的每个输入,列出所有表达式并检查是否有解析为攻击者可控的数据。高风险场景包括:
run:actions/github-scriptscript:${{ }}- 、
github.event.issue.titlegithub.event.issue.body - 、
github.event.pull_request.title、github.event.pull_request.body、.head.ref.head.label - 、
github.event.comment.bodygithub.event.review.body - 、
github.event.pages.*.page_name、github.event.commits.*.messagegithub.event.head_commit.* - 以及fork作者可设置的任何
github.head_ref字段github.event.*
请阅读获取完整的风险点列表和安全模式修复方案。
references/injection.mdStep 3 — Check Privileged Triggers Don't Execute Untrusted Code
步骤3 — 检查特权触发器是否执行不可信代码
If a or workflow checks out PR/fork code
() and then runs it (build, test, install
scripts, with lifecycle scripts, etc.), that is remote code execution against a
privileged token. Flag it as CRITICAL. The safe pattern is to split into two workflows: an
unprivileged workflow that runs the untrusted code, and a privileged
workflow that only consumes its results.
pull_request_targetworkflow_runref: ${{ github.event.pull_request.head.sha }}npm installpull_requestworkflow_run如果或工作流检出PR/fork代码()并运行(构建、测试、安装脚本、带生命周期脚本的等),则会针对特权令牌执行远程代码。标记为CRITICAL(严重)。安全模式是拆分为两个工作流:一个非特权的工作流运行不可信代码,一个特权的工作流仅消费其结果。
pull_request_targetworkflow_runref: ${{ github.event.pull_request.head.sha }}npm installpull_requestworkflow_runStep 4 — Audit permissions:
permissions:步骤4 — 审计permissions:
permissions:- If there is no block, the workflow inherits the repository default, which may be read/write to everything. Flag it.
permissions: - Recommend a top-level (deny-all) or
permissions: {}, then grant the minimum per job (e.g.contents: readonly on the job that comments).pull-requests: write - Flag any or broad
permissions: write-allscopes that the steps don't actually need.write
Read for the per-scope guidance and OIDC setup.
references/permissions-and-tokens.md- 如果没有块,工作流会继承仓库默认权限,可能对所有内容拥有读写权限。标记此问题。
permissions: - 建议使用顶层(拒绝所有权限)或
permissions: {},然后为每个作业授予最小必要权限(例如,仅在需要评论的作业中设置contents: read)。pull-requests: write - 标记任何或步骤实际不需要的宽泛
permissions: write-all权限范围。write
请阅读获取权限范围指南和OIDC设置说明。
references/permissions-and-tokens.mdStep 5 — Audit Action References (Supply Chain)
步骤5 — 审计Action引用(供应链)
For every :
uses:- Third-party actions (not or
actions/*) MUST be pinned to a full 40-character commit SHA, not a tag or branch. Tags and branches are mutable; a compromised upstream action can rewritegithub/*to malicious code that runs with your token and secrets.v1 - First-party are lower risk but SHA-pinning is still the hardened recommendation.
actions/* - Flag ,
@main, or any branch reference as HIGH — that is "latest" and can change under you at any time.@master - Note the human-readable version in a trailing comment: .
uses: foo/bar@<sha> # v2.1.0
Read for pinning, Dependabot for actions, and artifact/cache risks.
references/supply-chain.md对于每个:
uses:- 第三方Action(非或
actions/*)必须固定到完整的40字符提交SHA,而非标签或分支。标签和分支是可变的;被攻陷的上游Action可将github/*重写为恶意代码,使用你的令牌和密钥运行。v1 - 第一方风险较低,但仍建议固定SHA版本以强化安全。
actions/* - 标记、
@main或任何分支引用为HIGH(高风险)——这代表“最新版本”,随时可能发生变化。@master - 在末尾注释中添加可读版本:。
uses: foo/bar@<sha> # v2.1.0
请阅读获取版本固定、Actions的Dependabot配置以及工件/缓存风险的相关内容。
references/supply-chain.mdStep 6 — Check Secret and Output Handling
步骤6 — 检查密钥与输出处理
- No secrets echoed, printed, or written to logs; no /
set -xin steps that touch secrets.bash -x - Secrets must not be passed to steps that run untrusted code or to untrusted third-party actions.
- Untrusted multiline data written to or
$GITHUB_ENVcan inject environment variables or step outputs — use the random-delimiter heredoc form and never write raw user input.$GITHUB_OUTPUT - leaves a token on disk by default; set
actions/checkoutwhen the job later runs untrusted code.persist-credentials: false
- 不得在日志中回显、打印或写入密钥;在涉及密钥的步骤中不得使用/
set -x。bash -x - 不得将密钥传递给运行不可信代码的步骤或不可信第三方Action。
- 写入或
$GITHUB_ENV的不可信多行数据可能注入环境变量或步骤输出——请使用随机分隔符的heredoc格式,切勿写入原始用户输入。$GITHUB_OUTPUT - 默认会在磁盘上留下令牌;当作业后续运行不可信代码时,请设置
actions/checkout。persist-credentials: false
Step 7 — Produce the Report
步骤7 — 生成报告
Output findings using the format in : a severity summary table first,
then grouped findings with file, the exact offending YAML, the risk in plain English, and a
concrete before/after fix. Never auto-apply changes — present them for review.
references/report-format.md使用中的格式输出结果:首先是严重性汇总表,然后是按分组的问题,包含文件、确切的问题YAML代码、用通俗易懂的语言描述风险,以及具体的修复前后对比。切勿自动应用更改——请提供方案供审核。
references/report-format.mdSeverity Guide
严重性指南
| Severity | Meaning | Example |
|---|---|---|
| 🔴 CRITICAL | Token/secret theft or RCE reachable by an outside contributor | |
| 🟠 HIGH | Exploitable supply-chain or scope problem | Third-party action on a mutable tag/branch; |
| 🟡 MEDIUM | Risk under conditions or chaining | Missing |
| 🔵 LOW | Hardening gap, low direct risk | First-party action not SHA-pinned; |
| ⚪ INFO | Observation, not a vulnerability | Version comment missing next to a pinned SHA |
| 严重性 | 含义 | 示例 |
|---|---|---|
| 🔴 CRITICAL | 外部贡献者可获取令牌/密钥或执行远程代码 | |
| 🟠 HIGH | 可被利用的供应链或权限范围问题 | 第三方Action使用可变标签/分支; |
| 🟡 MEDIUM | 特定条件下或需链式触发的风险 | 缺失 |
| 🔵 LOW | 加固缺口,直接风险低 | 第一方Action未固定SHA版本;非特权作业中 |
| ⚪ INFO | 观察结果,非漏洞 | 固定SHA旁缺失版本注释 |
Output Rules
输出规则
- Always show a findings summary table (counts by severity) first.
- Group by issue type, not by file.
- Be exact — quote the offending line and give the line location.
- Always pair every CRITICAL/HIGH with a concrete corrected YAML snippet.
- Never claim a fork is dangerous just because it runs untrusted code — it has no secrets and a read-only token. Reserve CRITICAL for the privileged triggers.
pull_request - If the workflow is already hardened, say so and list what was checked.
- 必须首先显示问题汇总表(按严重性统计数量)。
- 按问题类型分组,而非按文件分组。
- 精确描述——引用问题行并给出行号位置。
- 必须为每个CRITICAL/HIGH级问题搭配具体的修正后YAML代码片段。
- 切勿仅因为fork的运行不可信代码就判定其危险——它无密钥且使用只读令牌。仅对特权触发器标记CRITICAL。
pull_request - 如果工作流已完成加固,请明确说明并列出已检查的内容。
Reference Files
参考文件
Load these as needed:
- — Trust matrix for every trigger, why
references/triggers-and-privilege.mdandpull_request_targetare privileged, and the two-workflow safe pattern.workflow_run- Search patterns: ,
pull_request_target,workflow_run,issue_comment,fork,secrets,read-only tokentrust boundary
- Search patterns:
- — Full list of attacker-controllable
references/injection.mdcontexts and the${{ }}-variable safe pattern for each sink (env:,run, action inputs).github-script- Search patterns: ,
script injection,github.event,head_ref,issue title,env,intermediate variableactions/github-script
- Search patterns:
- —
references/permissions-and-tokens.mdscopes, least-privilegeGITHUB_TOKENrecipes per job type, and OIDC for cloud auth instead of long-lived secrets.permissions:- Search patterns: ,
permissions,GITHUB_TOKEN,write-all,contents: read,id-token,OIDCleast privilege
- Search patterns:
- — SHA-pinning third-party actions, Dependabot for
references/supply-chain.md, artifact and cache poisoning acrossgithub-actions, and self-hosted runner exposure.workflow_run- Search patterns: ,
SHA pin,uses,mutable tag,Dependabot,download-artifact,cacheself-hosted runner
- Search patterns:
- — Output template: summary table, finding cards, and before/after remediation blocks.
references/report-format.md- Search patterns: ,
report,format,finding,summary,remediation,beforeafter
- Search patterns:
按需加载以下文件:
- — 所有触发器的信任矩阵,解释
references/triggers-and-privilege.md和pull_request_target为何属于特权触发器,以及双工作流安全模式。workflow_run- 搜索关键词:,
pull_request_target,workflow_run,issue_comment,fork,secrets,read-only tokentrust boundary
- 搜索关键词:
- — 攻击者可控的
references/injection.md场景完整列表,以及每个风险点(${{ }},run, Action输入)的github-script变量安全模式。env:- 搜索关键词:,
script injection,github.event,head_ref,issue title,env,intermediate variableactions/github-script
- 搜索关键词:
- —
references/permissions-and-tokens.md权限范围,按作业类型划分的最小权限GITHUB_TOKEN配置示例,以及使用OIDC进行云身份验证替代长期密钥的方案。permissions:- 搜索关键词:,
permissions,GITHUB_TOKEN,write-all,contents: read,id-token,OIDCleast privilege
- 搜索关键词:
- — 第三方Action的SHA版本固定、
references/supply-chain.md的Dependabot配置、github-actions间的工件和缓存投毒,以及自托管运行器暴露风险。workflow_run- 搜索关键词:,
SHA pin,uses,mutable tag,Dependabot,download-artifact,cacheself-hosted runner
- 搜索关键词:
- — 输出模板:汇总表、问题卡片、以及修复前后对比块。
references/report-format.md- 搜索关键词:,
report,format,finding,summary,remediation,beforeafter
- 搜索关键词: