GitHub Actions workflow dispatch 命令注入的概念验证实验室
CVE-2026-39866 是 Lawnchair 的 GitHub Actions 发布工作流中的一个命令注入漏洞。release_update.yml 文件将用户输入直接传递给 bash 而未加引号,因此攻击者可以注入命令。本仓库并排运行易受攻击版本和已修补版本。
该漏洞存在于 release_update.yml 工作流文件中。该操作接受一个 artifactName 参数,并将其直接传递给 bash 命令而未加引号。
- name: Rename artifact
run: mv ${{ inputs.artifactName }}.zip lawnchair.zip
GitHub Actions 在 shell 运行之前将变量值替换到字符串中。由于 ${{ inputs.artifactName }} 周围没有引号,shell 会将空格和分号解释为命令分隔符。
如果攻击者提供 file.zip; touch pwned.txt # 作为 artifactName:
GitHub Actions 如何解析它:
${{ inputs.artifactName }} → file.zip; touch pwned.txt #
Shell 如何执行它:
mv file.zip; touch pwned.txt #.zip lawnchair.zip
Shell 执行 mv file.zip,然后执行 touch pwned.txt,然后将其余部分作为注释忽略。
GITHUB_TOKEN 或发布签名密钥)。git clone https://github.com/abhayclasher/CVE-2026-39866.git
cd CVE-2026-39866/app
npm install
node server.js
git clone https://github.com/abhayclasher/CVE-2026-39866.git
cd CVE-2026-39866
docker compose up -d
服务器启动后,访问以下 URL:
| URL | 描述 |
|---|---|
http://localhost:3000/workflow/vulnerable | 易受攻击的工作流 — 提交时执行命令注入 |
http://localhost:3001/workflow/patched | 应用了 fcba413 补丁的相同工作流 |
易受攻击的版本将在运行器上执行您注入的命令。已修补的版本将输入视为字面字符串。
您也可以运行独立的 PoC:
cd poc
node exploit.js
这将在 3000 端口启动一个最小服务器,演示相同的漏洞,而无需完整的应用程序上下文。
1. 攻击者控制 artifactName 输入参数
2. GitHub Actions 将 ${{ inputs.artifactName }} 展开到 YAML 中
3. run 步骤将其发送给 bash
4. Bash 看到未加引号的特殊字符,并将其视为命令语法
5. 命令以运行器环境权限执行
┌────────────────────────────────────────────────────┐
│ 1. 恶意输入: │
│ │
│ artifactName = "file.zip; id #" │
│ │
│ 2. GitHub Actions 替换到 YAML 中: │
│ │
│ run: mv file.zip; id #.zip lawnchair.zip │
│ │
│ 3. Bash 看到: │
│ - mv file.zip │
│ - id <-- 任意命令 │
│ - #.zip lawnchair.zip(被忽略) │
│ │
│ 4. Shell 执行任意命令 │
└────────────────────────────────────────────────────┘
版本 fcba413 在插值变量周围引入了引号:
- name: Rename artifact
run: mv "${{ inputs.artifactName }}.zip" lawnchair.zip
引号可防止 shell 解析特殊字符。有效载荷将保持为字面文件名字符串。
最佳实践是使用环境变量来完全隔离用户输入:
- name: Rename artifact
env:
ARTIFACT_NAME: ${{ inputs.artifactName }}
run: mv "$ARTIFACT_NAME.zip" lawnchair.zip
查看完整提交:fcba413
CVE-2026-39866/
├── README.md # 本文件
├── docker-compose.yml # Docker 实验室配置
├── app/
│ ├── Dockerfile # 容器构建配置
│ ├── package.json # Node.js 依赖
│ └── server.js # 易受攻击 + 已修补工作流运行器模拟
└── poc/
└── exploit.js # 独立的最小概念验证
由 Abhay Kumar 报告。本仓库仅供本地教育用途。请勿在公共网络上部署易受攻击的服务器。
仅供教育目的 — 请在隔离环境中使用
| 字段 | 值 |
|---|
| CVE ID | CVE-2026-39866 |
| GHSA | GHSA-9prc-pp2c-3427 |
| CWE | CWE-78(OS 命令中特殊元素的不当中和) |
| 产品 | LawnchairLauncher/lawnchair |
| 受影响版本 | 所有低于 fcba413 的版本 |
| 已修补版本 | fcba413 |
| 发现者 | Abhay Kumar (@abhayclasher) |