From f09f515df5420498b85ee4211bcb62c7ed987a5d Mon Sep 17 00:00:00 2001 From: Thibaud-Vdb Date: Mon, 3 Aug 2026 10:10:46 +0200 Subject: [PATCH 1/2] ci: pin github actions to commit shas Mutable tags are movable pointers: whoever controls an action, or anyone who compromises it, can re-point the tag and the next run executes unreviewed code with the job's token. The sensitive spot here is release.yml, where release-please and the publish jobs run with release credentials. Same pattern as the tj-actions/changed-files incident (CVE-2025-30066). Pinning to the full commit sha freezes what runs; the version each sha corresponds to stays as a comment. Every sha was resolved from the upstream repository and cross-checked against its release tag. No workflow logic changes. --- .github/workflows/deploy-website.yml | 8 ++++---- .github/workflows/release.yml | 14 +++++++------- .github/workflows/test-website.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml index db7a03b8..3eca1f32 100644 --- a/.github/workflows/deploy-website.yml +++ b/.github/workflows/deploy-website.yml @@ -26,10 +26,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 - name: Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version: 24 cache: npm @@ -55,7 +55,7 @@ jobs: GOOGLE_MAPS_API_KEY_EXAMPLES: ${{ secrets.GOOGLE_MAPS_API_KEY_EXAMPLES }} - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 with: path: ./website/build @@ -75,4 +75,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b2bc953c..9c6daf82 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: # Run release-please on main pushes to open/update the release PR or cut a release. - name: Release Please id: release - uses: googleapis/release-please-action@v4 + uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1 with: release-type: node @@ -40,10 +40,10 @@ jobs: steps: # Publish the stable release when release-please created a GitHub release. - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 - name: Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version: 24 cache: npm @@ -69,7 +69,7 @@ jobs: steps: - name: Validate prerelease request id: gate - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | const body = context.payload.comment?.body || ''; @@ -134,12 +134,12 @@ jobs: needs: check-prerelease steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: ref: ${{ needs.check-prerelease.outputs.head_sha }} - name: Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version: 24 cache: npm @@ -190,7 +190,7 @@ jobs: echo "prNumber=$PR_NUMBER" >> $GITHUB_OUTPUT - name: Comment on PR - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 env: PR_NUMBER: ${{ steps.extract-pr.outputs.prNumber }} VERSION: ${{ steps.semver.outputs.version }} diff --git a/.github/workflows/test-website.yml b/.github/workflows/test-website.yml index 369a851e..fb3bdf98 100644 --- a/.github/workflows/test-website.yml +++ b/.github/workflows/test-website.yml @@ -7,10 +7,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 - name: Setup node - uses: actions/setup-node@v6 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version: 24 cache: npm diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9e45c75f..24bdde74 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,10 +5,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 - name: Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version: 24 cache: npm From 2bbe94e0ad7bab812d6aa706fa29db2b8b59091a Mon Sep 17 00:00:00 2001 From: Thibaud-Vdb Date: Mon, 3 Aug 2026 10:10:53 +0200 Subject: [PATCH 2/2] ci: declare workflow permissions explicitly Without a permissions block, the test jobs' GITHUB_TOKEN inherits the repository default scope. Both only check out and build (the website build reads its API key from a dedicated secret, the GitHub token is unused), so they get contents read. The deploy and release workflows already declare scoped permissions and are untouched. --- .github/workflows/test-website.yml | 3 +++ .github/workflows/test.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/test-website.yml b/.github/workflows/test-website.yml index fb3bdf98..5d8d459b 100644 --- a/.github/workflows/test-website.yml +++ b/.github/workflows/test-website.yml @@ -1,6 +1,9 @@ name: Website Test on: [push, pull_request] +permissions: + contents: read + jobs: build: name: Build Website diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 24bdde74..482fbd5d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,8 @@ name: Test on: [push, pull_request] +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest