GitHub Actions
允许的不安全命令
有一些已弃用的 set-env 和 add-path 工作流命令,可以通过将 ACTIONS_ALLOW_UNSECURE_COMMANDS 环境变量设置为 true 来显式启用。
set-env通过以下工作流命令设置环境变量::set-env name=<NAME>::<VALUE>add-path通过以下工作流命令更新PATH环境变量::add-path::<VALUE>
根据环境变量的使用情况,在最坏的情况下,这可能允许攻击者更改路径并运行非预期的命令,导致任意命令执行。例如,考虑以下工作流:
name: 易受攻击的工作流
on:
pull_request_target
env:
# 1. 启用不安全命令
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
ENVIRONMENT_NAME: prod
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 2. 打印 github 上下文
- run: |
print("""${{ toJSON(github) }}""")
shell: python
- name: 创建新的 PR 部署
uses: actions/github-script@v5
with:
# 3. 创建部署
script: |
return await github.rest.repos.createDeployment({
...context.repo,
ref: context.payload.pull_request.head.sha,
auto_merge: false,
required_contexts: [],
environment: "${{ env.ENVIRONMENT_NAME }}",
transient_environment: false,
production_environment: false,
});
github-token: ${{ secrets.GITHUB_TOKEN }}上述工作流通过在 env 部分将 ACTIONS_ALLOW_UNSECURE_COMMANDS 设置为 true 来启用不安全命令。可以看到,deploy 作业的第一步将 github 上下文打印到工作流日志中。由于 github 上下文中的部分变量是用户控制的,可能滥用不安全命令来设置任意环境变量。例如,攻击者可以使用拉取请求描述来传递以下payload,当打印 github 上下文时,这将重置 ENVIRONMENT_NAME:
\n::set-env name=ENVIRONMENT_NAME::", <YOUR_JS_CODE>//\n现在让我们看看上述payload的工作原理:

由于 payload 使用了 ::set-env name=ENVIRONMENT_NAME:: 命令,它将把环境变量 ENVIRONMENT_NAME 重置为 ", <YOUR_JS_CODE>//。因此,在 github-script 中,environment 将被设置为 ", <YOUR_JS_CODE>// 而不是 prod。然后,攻击者可以通过精心设计的 YOUR_JS_CODE 注入任意 JavaScript 代码。
参考资料
脚本注入
GitHub Actions 允许您使用各种shell在运行器上执行命令。这些shell包括 bash、pwsh、powershell 和 python。然而,在某些情况下,GitHub Actions 会将用户控制的输入直接传递给shell命令,这可能导致命令注入。
例如,考虑以下易受攻击的工作流:
name: 易受攻击的工作流
on:
pull_request_target
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 获取 PR 编号
id: pr-number
run: |
echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
- name: 注入命令
run: |
# 用户控制的输入
PR_NUMBER=${{ env.PR_NUMBER }}
# 直接传递给 shell
echo "Processing PR #$PR_NUMBER"
# 易受攻击的命令执行
./deploy.sh --pr $PR_NUMBER在上述示例中,攻击者可以通过将恶意payload注入到PR标题或描述中来执行任意命令。例如,如果攻击者创建一个标题为 1; rm -rf / 的PR,这将导致执行 rm -rf / 命令。
为了防止此类攻击,应该:
验证和清理所有用户控制的输入
使用安全的参数传递方法
避免直接将用户输入传递给shell命令
参考资料
权限提升
GitHub Actions 运行器默认具有与仓库相同的权限。在某些情况下,这可能导致权限提升,特别是当工作流使用敏感的 secrets.GITHUB_TOKEN 时。
考虑以下示例:
name: 易受攻击的工作流
on:
pull_request_target
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 创建 PR 部署
uses: actions/github-script@v5
with:
script: |
// 攻击者可以修改此代码
return await github.rest.repos.createDeployment({
...context.repo,
ref: context.payload.pull_request.head.sha,
auto_merge: false,
required_contexts: [],
environment: "production",
transient_environment: false,
production_environment: false,
});
github-token: ${{ secrets.GITHUB_TOKEN }}在上述示例中,攻击者可以通过修改 github-script 来创建生产环境的部署,即使原始工作流只打算用于测试环境。
参考资料
最后更新于