indoor47/gh-workflow-hardener

GitHub: indoor47/gh-workflow-hardener

专注于 GitHub Actions 工作流的安全扫描工具,检测未固定版本引用、危险权限和脚本注入等供应链安全风险。

Stars: 0 | Forks: 0

# gh-workflow-hardener [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/) **保护您的 GitHub Actions 工作流免受供应链攻击。** 检测未固定版本的操作(tj-actions 攻击向量)、危险权限以及脚本注入——一次扫描即可完成。 在 [tj-actions 供应链攻击](https://www.crowd.dev/blog/github-actions-supply-chain-attack) 入侵了 23k+ 个仓库后,团队们意识到:GitHub Actions 工作流是一个安全盲点。此工具旨在解决这一问题。 ## 检测内容 ### 🔴 严重问题 - **未固定版本的操作 (Unpinned actions)** — 未通过 commit SHA 固定的操作容易受到恶意标签重写攻击。示例: - uses: actions/checkout@v3 # 🔴 易受攻击 — 固定在 tag,而非 SHA - uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45aca646fdde3 # ✅ 安全 - **危险权限** — 过于宽泛的权限(`permissions: write-all` 或缺少显式拒绝)。示例: permissions: contents: write issues: write pull-requests: write # 真的需要这个吗? - **脚本注入** — 运行步骤中使用了来自 PR 的未经清理的输入。示例: - run: echo ${{ github.event.pull_request.title }} # 🔴 易受攻击 ### 🟡 高/中危问题 - 缺少 `permissions` 块(默认为宽泛访问权限) - Secrets 作为环境变量传递(应使用 `secrets:` 方式) - 在外部操作中可疑地使用 `github.token` ### 📋 低危问题 - 已弃用的操作版本 - 构建前缺少 checkout 步骤 - 未经审查的第三方操作 ## 托管 API(无需安装) 通过单次 HTTP 调用扫描任意公开仓库: ``` # 扫描 GitHub 仓库 curl -X POST http://89.167.76.186:8000/scan \ -H 'Content-Type: application/json' \ -d '{"repo": "owner/repo"}' # 扫描原始 workflow YAML curl -X POST http://89.167.76.186:8000/scan \ -H 'Content-Type: application/json' \ -d '{"yaml": "name: test\non: push\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4"}' ``` 响应: ``` { "files_scanned": 19, "issues": [...], "summary": {"total": 105, "critical": 85, "high": 20, "medium": 0, "low": 0} } ``` 免费,无需认证。 ## 安装 ### 作为 CLI 工具 **选项 1:Homebrew (macOS & Linux)** ``` brew tap indoor47/homebrew-gh-workflow-hardener brew install gh-workflow-hardener ``` **选项 2:从源码安装** ``` git clone https://github.com/indoor47/gh-workflow-hardener cd gh-workflow-hardener pip install . ``` ### 作为 GitHub Action(推荐) 添加到 `.github/workflows/security-check.yml`: ``` name: Workflow Security Check on: pull_request: paths: - '.github/workflows/**' push: branches: - main paths: - '.github/workflows/**' permissions: contents: read jobs: hardener: runs-on: ubuntu-latest steps: - uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45aca646fdde3 - uses: indoor47/gh-workflow-hardener@bd2a0a1f06117de11bd7da6b62b80087596f569f # v1.1.0 with: fail_on: critical ``` ## 使用方法 ### CLI ``` # 扫描当前仓库 (需要 .github/workflows/) gh-workflow-hardener # 扫描特定仓库 gh-workflow-hardener /path/to/repo # 输出为 JSON (用于 CI 集成) gh-workflow-hardener --format json # 输出为 SARIF (用于 GitHub Code Scanning) gh-workflow-hardener --format sarif # 通过将 tags 解析为 commit SHAs 来自动修复未固定的 actions gh-workflow-hardener --fix --token $GITHUB_TOKEN # 仅在 critical + high severity 问题时失败 gh-workflow-hardener --fail-on high ``` ### 输出示例 ``` GitHub Actions Workflow Security Report ========================================= .github/workflows/build.yml [CRITICAL] Line 12: Unpinned action: actions/checkout@v3 → Pin to: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45aca646fdde3 [HIGH] Line 45: Overly broad permissions → Found: permissions: write-all → Fix: Specify only needed permissions .github/workflows/deploy.yml [MEDIUM] Line 8: Secrets passed as env var → Use: secrets: { AWS_KEY: ${{ secrets.AWS_KEY }} } ========================================= Issues: 3 critical, 1 high, 1 medium Status: FAIL (--fail-on critical) ``` ## 真实世界结果 我们扫描了 8 个热门开源仓库的工作流(2026 年 2 月): | 仓库 | Stars | Workflows | 发现数 | 评分 | |---|---|---|---|---| | facebook/react | 236k | 20 | 197 | 0/100 | | vercel/next.js | 132k | 25 | 143 | 0/100 | | langchain-ai/langchain | 105k | 16 | 89 | 0/100 | | django/django | 83k | 16 | 56 | 0/100 | | fastapi/fastapi | 82k | 19 | 121 | 0/100 | | microsoft/vscode | 170k | 12 | 66 | 0/100 | | astral-sh/ruff | 40k | 19 | 8 | 40/100 | | pallets/flask | 69k | 4 | 6 | 55/100 | **131 个工作流文件中共发现 686 个问题。零误报。** 73% 的发现是未固定版本的操作引用,这正是 [tj-actions 攻击](https://www.crowd.dev/blog/github-actions-supply-chain-attack) 中被利用的漏洞。已经固定到 SHA 的仓库(ruff, flask)得分明显更高。 ## 为什么这很重要 tj-actions 攻击表明,单个受损的操作可以: - 窃取仓库 secrets 和 tokens - 修改 Pull Request 中的代码 - 窃取源代码 - 注入恶意依赖 通过将操作固定到特定的 commit SHA 并验证权限,您可以消除整个攻击向量。 ## GitHub Action 输入 | 输入 | 默认值 | 描述 | |-------|---------|-------------| | `fail_on` | `critical` | 如果发现此严重级别或更高的问题,则退出并报错。选项:`critical`、`high`、`medium`、`low`、`none` | | `format` | `text` | 输出格式:`text`、`json`、`markdown`、`sarif` | | `fix` | `false` | 通过固定到 commit SHA 自动修复未固定版本的操作 | | `github_token` | `${{ github.token }}` | 用于 SHA 解析的 GitHub token(自动修复时需要) | ## 零依赖 (CLI) CLI 仅需 `pyyaml` 和 `click`。无重型扫描框架,无臃肿。快速。可审计。 ## VS Code 扩展 喜欢在输入时捕获问题?配套的 [**GitHub Workflow Hardener**](https://github.com/indoor47/vscode-workflow-hardener) VS Code 扩展可在您编辑 `.github/workflows/` 文件时实时运行相同的检查——无需 CLI。 ## 贡献 发现了误报?有更好的检测规则?欢迎提交 Issue 或 PR。 ## 许可证 MIT
标签:CI/CD 安全, DevSecOps, GitHub Actions, GitHub 安全, GraphQL安全矩阵, Python, SAST, SHA 锚定, YAML 解析, 上游代理, 云安全监控, 安全扫描器, 工作流加固, 数据投毒防御, 文档安全, 文档结构分析, 无后门, 权限审计, 盲注攻击, 结构化查询, 脚本注入检测, 自动化安全, 自动笔记, 软件开发工具包, 逆向工具, 静态分析