我把 GitHub Actions secrets 配了三年,今天才发现它们的名称早就被人看光了——Wiz 的研究把这件事彻底扒了

我把 GitHub Actions secrets 配了三年,一直以为把它们放在 Environment Secrets 里就高枕无忧了。结果 Wiz 最新的研究告诉我——错了。Secrets 的名称早就被人摸清了,你锁住的只是值,不是名字。

今天把这件事彻底拆清楚。

问题:你的 secrets 名称根本不是秘密

GitHub Actions 的 workflow 文件里经常能看到这种写法:

- name: Deploy to production
  env:
    API_KEY: ${{ secrets.API_KEY }}
    DATABASE_URL: ${{ secrets.DATABASE_URL }}

${{ secrets.API_KEY }} 这个语法本身没问题,但你有没有想过——这个文件如果推到公开仓库,或者攻击者有仓库的读权限(甚至只是基本读取权限),他就能通过 GitHub API 搜索所有包含 secrets. 的代码。

Wiz 的研究团队发现:拥有仓库基本读取权限的攻击者,可以通过 GitHub 代码搜索直接找到 secrets 的名称。这些名称本身就构成了情报——知道用的是哪个云服务商、哪个 API、哪个数据库,就能定向攻击。

更可怕的是,GitHub Actions 的 workflow 文件历史记录里,这些名称可能一直存在,即使你后来删了 secrets,环境变量名已经从代码里消失了,但攻击者可以用同样的方法挖出历史版本。

攻击路径:四步拿到云环境访问

第一步:通过 GitHub API 搜索所有公开仓库里包含 ${{ secrets. 的 workflow 文件,找到云服务商相关的名称(AWS、Azure、GCP)

第二步:根据名称推断环境。比如 AWS_ACCESS_KEY_ID + production 出现在同一个 workflow 里,说明这个 key 对应的是生产环境 AWS

第三步:拿着 key 名称去对应的云平台尝试访问。如果配合其他泄露的凭证或者默认配置,直接进云环境

第四步:在云环境里横向移动,拿数据、拿权限、拿持久化

整个过程不需要任何特殊权限,只需要一个 GitHub 账号的基本读取权限。

怎么防:四层加固

第一层:Environment Secrets

不要把 secrets 直接放在仓库的 Settings → Secrets and variables → Actions 里,而是创建 Environments(生产环境、预发环境、测试环境),把 secrets 放在对应 Environment 下。

jobs:
  deploy:
    environment: production  # secrets 属于这个 Environment
    steps:
      - run: npm run deploy
        env:
          API_KEY: ${{ secrets.API_KEY }}

这样 secrets 的访问权限可以精细化到指定团队成员,需要审批才能读取。

第二层:不要在 workflow 文件里暴露 secrets 名称

如果 workflow 只是引用某个 secret,不要在注释或者文档里写出完整名称。

# ✅ 好:只在 env 里引用,不写名称注释
- run: deploy.sh
  env:
    DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}

# ❌ 差:名称直接暴露在注释里
# Use AWS_ACCESS_KEY_ID from production environment
- run: deploy.sh
  env:
    AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }}

第三层:用 OpenID Connect(OIDC)替代静态凭证

静态 API Key 最大的问题是”一旦泄露就是永久泄露”。用 OIDC 做云资源访问,可以让 GitHub Actions 在每次运行时动态申请临时 token,Key 根本不需要存在 secrets 里。

AWS 示例:

- name: Configure AWS Credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789:role/github-actions-role
    aws-region: us-east-1

这样 GitHub Actions 用的是临时 token,不是静态 Key。即使有人看到 role 名称,也没有长期有效的凭证可用。

第四层:限制 workflow 文件的历史可见性

对于敏感 workflow,可以用权限控制减少历史记录的可见范围:

permissions:
  contents: read
  actions: read
  environments: production

contents 权限最小化,降低通过 git 历史挖取 secrets 名称的可能性。

怎么检查自己的仓库有没有这个问题

用 GitHub 代码搜索,搜 ${{ secrets. 加上你的云服务商关键词,看看结果:

${{ secrets.AWS_SECRET_ACCESS_KEY }}
${{ secrets.AZURE_CLIENT_SECRET }}
${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}

如果自己的仓库里有结果,说明 workflow 文件里有 secrets 名称泄露。

也可以用 Wiz 的开源工具或者 GitHub Advanced Security 的 secret scanning 功能做全面审计。


配 GitHub Actions 配了三年,我一直以为把 secrets 藏在 Environment Settings 里就安全了。今天发现,防护从来不只是”值”,还有”名”——云服务商的 key 名称本身就够攻击者拼出攻击路径了。用 OIDC 替代静态 Key、把 key 名称从 workflow 注释里删掉、给 Environment 加访问审批,这三件事做完,这个攻击面才算真正锁上。

评论区

0 条评论

登录后可评论。

阿监·前端工程化 589 阅读