flawopen.com/GitHub Actions 安全/工作流脚本注入
GitHub Actions 如何发生脚本注入,怎样防范?
高权限下影响严重
CWE-78
CI/CD 工作流安全
通俗解释
工作流若在 Bash 启动前把 issue 标题或 pull request 字段插入脚本,就可能把数据变成 shell 语法。就像把姓名误当成指令的名牌打印机。通过环境变量传值,并在作为数据使用时给 shell 展开加引号,Bash 就会把值作为独立数据接收。实际影响还取决于令牌、机密、runner 和触发事件。
不可信上下文GitHub 事件字段,如标题、正文、分支名、标签和提交消息。视为外部用户可控字符串。
表达式替换GitHub 在 shell 启动前求值
${{ ... }}。在 run: 中,输入可能被拼进脚本源码。环境变量传递映射到
env: 会将值作为进程数据传递。给 shell 展开加引号,并避免 eval 或动态脚本。权限边界事件和工作流决定令牌权限、机密及 runner 访问范围。影响受限于 job 可访问的资源。
根因:shell 解析前已插入数据
GitHub 在启动 run 步骤的 shell 前展开表达式。若不可信标题直接插入脚本,其字符可能改变 shell 程序,而非保留为数据。通过 env: 传值会使其与脚本文本分离;加引号后,在普通命令中仍作为参数。但这不能保护后续传给 eval、其他解释器或将参数当代码的工具。GitHub 将事件字段视为可能由攻击者控制的输入。
.github/workflows/triage.yml(不安全插值)不安全
# 不安全:事件数据会进入生成的 shell 脚本
name: Issue Triage
on:
issues:
types: [opened]
permissions:
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Print issue title
run: |
printf 'Title: %s\n' "${{ github.event.issue.title }}"
.github/workflows/triage.yml(数据分离)已加固
# 更安全:通过环境变量传递事件值
name: Issue Triage
on:
issues:
types: [opened]
permissions:
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Print issue title
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
run: |
printf 'Title: %s\n' "$ISSUE_TITLE"
攻击路径概览
Step 1
用户控制事件字段
例如公开 issue 标题、pull request 标题或分支名称成为工作流输入。
Step 2
工作流将其拼入 shell 源码
run: 中直接使用的 ${{ github.event... }} 会在 Bash 解析脚本前求值。
Step 3
shell 解释被改变的程序
若该值改变 shell 语法,命令会以 job 进程身份运行。若值始终是加引号的参数数据,则不会形成这种注入。
Step 4
job 权限决定影响范围
被攻陷的 job 只能访问本次运行暴露的资源,包括有效 GITHUB_TOKEN 权限、提供的机密和 runner。仔细审查 issue 事件与 pull_request_target。
加固检查清单
- ✓不要把不可信
github.event值直接插入run:。通过env:传递,并给"$ISSUE_TITLE"这类展开加引号。 - ✓让不可信值远离
eval、生成脚本、shell 命令字符串,以及将参数解释为代码或选项的工具。 - ✓在 workflow 或 job 设置严格
permissions:,仅向确需的 job 授予写权限。 - ✓将
pull_request_target和workflow_run视作特权边界。不要在此上下文检出、构建或执行不可信 PR 代码或制品。 - ✓不要把不可信多行数据写入
GITHUB_ENV或GITHUB_PATH。GitHub 禁止覆盖GITHUB_*和RUNNER_*,但其他值仍可能影响后续步骤。 - ✓第三方 Action 固定到已审查的完整 SHA;不可信 job 使用隔离且短暂的 runner,并为 Actions 工作流启用 CodeQL。
一手来源
- GitHub 文档 — 脚本注入
- GitHub 文档 — 安全使用参考
- GitHub 文档 — 安全使用 pull_request_target
- GitHub 文档 — 工作流命令与 GITHUB_ENV
- GitHub 文档 — GITHUB_TOKEN 权限
浏览相关安全主题与事故分析:完整安全目录 →