CI Token权限泄露
在公司推行 CI/CD 安全标准的时候,最让人头疼的不是没工具,而是工具报的警太“片面”。前段时间我在维护 mcpscan(一个扫描 MCP 配置和 GitHub Actions 工作流的静态扫描器)时就踩了个坑,原本以为写好了一条规则就能封堵 代码检出滥用: 直接检出
产物(Artifact)滥用: 下载前置运行产生的 Artifact 并直接执行。此时风险点在构建输出物。
下一篇
GPT-Red:给AI Agent加道“压力测试” →
workflow_run 的权限漏洞,结果上线第二天发现,它只能抓到一半的 Bug。很多开发者对 pull_request_target 的风险心知肚明,但 workflow_run 这种“静默漏洞”更容易被忽视。它的逻辑是:当另一个工作流结束时触发,且始终在默认分支运行,持有仓库的正常 Token。如果触发它的那个前置工作流可以被 Fork 的 PR 触发,那么一个不受信任的事件就被传递给了一个拥有高权限的 Job。
这种特权 Token 的滥用路径其实有两条,而我最初的规则只覆盖了其中一种:
github.event.workflow_run.head_sha 或 .head_branch。此时风险点在提交的代码本身。我最初在 v0.14.0 版本中定义的 MCP019 规则,不仅只盯着 Artifact 下载,还加了一个条件:只有在工作流没有定义 permissions: 限制块时才报警。
这种设计逻辑在表面上看起来提高了“信号质量”,但在实际工程中却制造了巨大的盲区。首先,直接检出 SHA 的路径被完全忽略了;其次,只要开发者写了任何一个 permissions 限制(哪怕范围很宽),规则就会认为该漏洞已处理。但事实上,只要不受信任的代码在特权 Job 中运行,缩小 Token 范围并不能从根本上消除执行风险。
来看一个典型的漏洞配置示例:
name: post-build
on:
workflow_run:
workflows: [Build]
types: [completed]
jobs:
post:
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Run whatever the triggering build produced
run: ./build-output/script.sh在这个例子中,最后一行 run: ./build-output/script.sh 就是致命伤。Fork 仓库的构建步骤产生了什么,这里就执行什么,完全没有校验。
为了解决这个问题,我在 v0.15.0 中将规则进行了拆分,不再让它们相互依赖。对于数据工程师或 DevOps 来说,这种 DX(开发体验)的教训就是:安全规则不能过度追求“精准”而通过增加耦合条件来降低误报,否则漏报带来的代价远高于处理几次误报。
