# GitHub Actions 安全指南:平衡 pull_request_target 与代码注入风险

在 GitHub Actions 中,使用 `pull_request_target` 触发器虽然能获取仓库的完整上下文(如 secrets),但也引入了显著的安全风险。该触发器会在拉取请求合并后或特定条件下运行,且拥有写入权限,若处理不当,攻击者可通过恶意 PR 注入代码窃取密钥或控制仓库。

## 核心原则:避免不必要的特权触发

GitHub 官方建议,除非工作流确实需要访问主分支缓存或执行写入操作,否则应避免使用 `pull_request_target`。对于仅需读取未受信任代码的场景,推荐使用 `workflow_run` 触发器,它能提供必要的隔离性。

## 处理未受信任代码的最佳实践

当必须处理来自拉取请求(尤其是 fork 仓库)的未受信任输入时,应遵循以下策略:

1. **使用中间环境变量**:不要直接将用户输入拼接到 shell 脚本中。将表达式值(如 `${{ github.event.pull_request.title }}`)先赋值给环境变量,再在脚本逻辑中使用。这能防止 Shell 注入攻击,因为变量值仅作为内存中的字符串处理,不会直接生成新的命令。
2. **最小权限原则**:确保工作流使用的 `GITHUB_TOKEN` 仅拥有完成当前任务所需的最小权限(如仅读取仓库内容)。避免默认授予写权限。
3. **锁定依赖版本**:始终使用锁文件(lockfile)或完整提交 SHA(commit SHA)来固定第三方动作和可复用工作流的版本。这能防止攻击者替换动作代码以植入后门。
4. **审计与隔离**:定期审查使用的第三方动作源码,确保其未将敏感数据发送至意外主机或未在日志中明文打印。对于自托管 runner,应极度谨慎,因为一旦环境被攻破,攻击者可持久化访问所有运行在该机器上的工作流。

## 利用 GitHub 原生安全功能

- **代码扫描**:启用 CodeQL 等代码扫描工具,自动检测潜在的安全漏洞模式。
- **OpenSSF Scorecards**:使用此工具自动识别供应链风险,包括脚本注入和未固定的动作。
- **Dependabot**:配置 Dependabot 监控依赖项更新,接收安全警报并自动修复已知漏洞。
- **CODEOWNERS**:为 `.github/workflows` 目录设置代码所有者,确保任何工作流文件的修改需经指定人员批准。

通过结合上述策略,您可以在享受 GitHub Actions 自动化能力的同时,有效构建防御供应链攻击和脚本注入的安全防线。

信息来源