跳转到主要内容
为应对针对 GitHub Actions 的攻击与篡改风险,官方 Laravel 项目也采用了一种安全对策——GitHub Actions 的固定(pinning)。本页面从包开发者的视角,实用地讲解应当采取的安全措施。
本页面是包开发基础的姊妹页面。前提是你已了解 GitHub Actions 的基本用法。

GitHub Actions 的安全风险

基于标签引用的隐患

通常,GitHub Actions 会像下面这样通过标签引用:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
这种做法的问题:
  • 标签可移动 — 标签可被删除后重新创建,保持同名
  • 篡改风险 — 仓库所有者账号被劫持后可注入恶意代码
  • 供应链攻击 — 若你依赖的 Action 被攻击,你的工作流也会受损

官方 Laravel 项目的做法

laravel/laravellaravel/framework 都将所有 Action 固定到提交哈希(SHA)。
# 安全的引用方式
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4

固定的落地策略

第 1 步:创建 Dependabot 配置文件

在包仓库中创建 .github/dependabot.yml。可以直接复用 Laravel 的文件。
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    cooldown:
      default-days: 5
    groups:
      github-actions:
        patterns:
          - "*"
这份文件负责:
  • 自动扫描 — 扫描 GitHub Actions 的新版本
  • 自动创建 PR — 当有更新可用时,自动创建更新 PR
  • 控制更新方式 — 未固定的 Action 按版本更新,已固定的按 SHA 更新

第 2 步:将现有 Action 固定到 SHA

将现有工作流中所有 Action 的引用改为 SHA 哈希。可以借助 pinact 等工具自动化。

使用 pinact 工具自动化

# 将工作流中的 Action 固定到 SHA
pinact run

手动修改

若无法使用 pinact,可以在 GitHub 的 Lookup latest version 页面查找每个 Action 的提交 SHA 并手动替换。
# 修改前
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
  with:
    php-version: ${{ matrix.php }}

# 修改后
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
- uses: shivammathur/setup-php@0a92e4568cab5c87b7175192630661408458a086  # v2
  with:
    php-version: ${{ matrix.php }}

第 3 步:启用 Dependabot 设置

.github/dependabot.yml 提交并推送到仓库后,Dependabot 会自动开始扫描。

Dependabot 的自动更新机制

Dependabot 会根据 dependabot.yml 的配置采用不同更新策略。

未固定的 Action

# 固定前
- uses: actions/checkout@v4
Dependabot 的更新方式:将版本范围升到新版本
# Dependabot 创建的 PR
- uses: actions/checkout@v5
这种方式偏向便捷,能应对标签的移动,但安全风险仍存在。

已固定的 Action

# 固定后
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
Dependabot 的更新方式:升到新版本的提交哈希
# Dependabot 创建的 PR
- uses: actions/checkout@f1d3225b54b677ba3e72df8c464cb6cf6dc1aebf  # v4
这种方式最为安全。新版本仍以提交哈希引用,对篡改具有更强抵抗力。

工作流实现示例

以下是多个工作流共同使用 Action 的完整示例。
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    strategy:
      fail-fast: false
      matrix:
        php: [8.2, 8.3, 8.4]
        laravel: ["^12.0", "^13.0"]

    steps:
      - uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
        with:
          fetch-depth: 0

      - name: Setup PHP
        uses: shivammathur/setup-php@0a92e4568cab5c87b7175192630661408458a086  # v2
        with:
          php-version: ${{ matrix.php }}
          extensions: dom, curl, libxml, mbstring, zip, intl, sqlite3
          coverage: none

      - name: Install dependencies
        run: |
          composer require "laravel/framework:${{ matrix.laravel }}" \
                           --no-interaction --no-update
          composer update --prefer-dist --no-interaction

      - name: Run tests
        run: vendor/bin/pest

  lint:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4

      - name: Setup PHP
        uses: shivammathur/setup-php@0a92e4568cab5c87b7175192630661408458a086  # v2
        with:
          php-version: "8.4"
          extensions: dom, curl, libxml, mbstring, zip
          coverage: none

      - name: Install dependencies
        run: composer install --prefer-dist --no-interaction

      - name: Run static analysis
        run: vendor/bin/phpstan

处理 Dependabot 的更新 PR

Dependabot 创建的更新 PR 可按下面的方式处理。

单个 Action 的更新 PR

Bump shivammathur/setup-php from v1 to v2
对这种简单更新,按以下步骤处理:
  1. 确认工作流执行结果
  2. 确认是否有破坏性变更
  3. 合并完成

安全更新 PR

[SECURITY] Bump actions/checkout to a5ac7e51b41094c7fcab2042361574b0021804ab
与安全修复相关的更新优先合并。

多个 Action 的分组更新

当在 dependabot.yml 中配置了 groups 时,多个 Action 会在同一个 PR 中一并更新。
groups:
  github-actions:
    patterns:
      - "*"
把所有 Action 的更新合并到一个 PR,可减少合并次数。

固定的收益与代价

收益

收益说明
抵御供应链攻击引用具体的提交哈希,可对抗 Action 的篡改
可审计性能追踪每个 Action 何时从哪个版本更新
显式更新Dependabot 会以 PR 形式提出更新,必然经过人工审核
可复现性同一提交哈希执行时,环境完全一致

代价

代价应对方式
初始需要手工设置使用 pinact 工具自动化
更新管理成本上升通过 Dependabot 自动创建 PR,把成本降到最低
可读性下降在注释中并列版本号以保持可读性

安全审计检查清单

在启动新包项目时可参考的检查清单。
  • 创建 .github/dependabot.yml
  • 将所有现有 Action 固定到 SHA
  • pinact 或手动核对完毕
  • 确认工作流可正常执行
  • 每周至少审查一次 Dependabot 的更新 PR
  • 优先合并安全相关的更新
  • 新增 Action 时务必以 SHA 引用
  • 每月检查一次全部工作流的状态
  • 确认所有 Action 引用均为 SHA
  • 确认 Dependabot 已启用
  • 确认过去 6 个月的 Dependabot PR 都已合并

相关页面

包开发基础

以 Service Provider 为核心讲解 Laravel 包的开发方式。

包的版本兼容性管理

应对 Laravel 主版本升级的包维护策略。
最后修改于 2026年7月13日