From 93befdbde6c1c117a78884f74bc263e34151936c Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Tue, 21 Apr 2026 18:14:00 +0000 Subject: [PATCH] security(ci): pin third-party GitHub Actions to commit SHAs `uses: action@v1` style references resolve to whatever commit the tag currently points at. Tag ownership is shared with the action maintainer, so a compromise of their account (or a malicious maintainer move) can silently rewrite the tag to point at a hostile commit without any change to our workflow files. The industry-standard mitigation is to pin every non-trusted action to a full commit SHA and keep the semver as a trailing comment for humans. Pin the two third-party actions used in Craft's workflows: - pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 (build.yml x3, docs-preview.yml x1, lint.yml x1) - rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1 (docs-preview.yml x1) Left unpinned by design: - actions/* (GitHub-owned; trust root). - getsentry/* (same org; separate trust boundary from third-party). - Local ./ and local reusable workflows (path-based, no tag drift). getsentry/action-enforce-license-compliance was already SHA-pinned. --- .github/workflows/build.yml | 6 +++--- .github/workflows/docs-preview.yml | 4 ++-- .github/workflows/lint.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 65fd73bb..7a763679 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: - name: Get pnpm version from Volta config id: pnpm-version run: echo "version=$(jq -r '.volta.pnpm' package.json)" >> $GITHUB_OUTPUT - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 with: version: ${{ steps.pnpm-version.outputs.version }} - uses: actions/cache@v5 @@ -57,7 +57,7 @@ jobs: - name: Get pnpm version from Volta config id: pnpm-version run: echo "version=$(jq -r '.volta.pnpm' package.json)" >> $GITHUB_OUTPUT - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 with: version: ${{ steps.pnpm-version.outputs.version }} - uses: actions/cache@v5 @@ -99,7 +99,7 @@ jobs: - name: Get pnpm version from Volta config id: pnpm-version run: echo "version=$(jq -r '.volta.pnpm' package.json)" >> $GITHUB_OUTPUT - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 with: version: ${{ steps.pnpm-version.outputs.version }} - name: Build Docs diff --git a/.github/workflows/docs-preview.yml b/.github/workflows/docs-preview.yml index 1eede48f..1f6682e6 100644 --- a/.github/workflows/docs-preview.yml +++ b/.github/workflows/docs-preview.yml @@ -24,7 +24,7 @@ jobs: - name: Get pnpm version from Volta config id: pnpm-version run: echo "version=$(jq -r '.volta.pnpm' package.json)" >> $GITHUB_OUTPUT - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 with: version: ${{ steps.pnpm-version.outputs.version }} @@ -69,7 +69,7 @@ jobs: fi - name: Deploy Preview - uses: rossjrw/pr-preview-action@v1 + uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1 with: source-dir: docs/dist/ preview-branch: gh-pages diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 94d55e47..6d3e3bc3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: - name: Get pnpm version from Volta config id: pnpm-version run: echo "version=$(jq -r '.volta.pnpm' package.json)" >> $GITHUB_OUTPUT - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 with: version: ${{ steps.pnpm-version.outputs.version }} - uses: actions/cache@v5