From 105a8bf9bf5ba4fcab9ee6ebac0244f8a80f3b74 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Wed, 27 May 2026 08:03:18 -0500 Subject: [PATCH] ci(spellcheck): pin misspell + add least-privilege permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three hardening fixes for .github/workflows/spellcheck.yml, ported from the same audit applied to the sister modules repo: 1. Add top-level 'permissions: contents: read'. Without an explicit block, the GITHUB_TOKEN inherits the repo default (typically read+write across most APIs), which is far more than misspell needs. misspell only walks .md/.txt/lib/tests files and prints typos to stdout; it never comments on PRs, posts statuses, or writes packages. This also satisfies CodeQL rule 'actions/missing-workflow-permissions' if Actions analysis is enabled here later (it isn't in the current codeql-analysis.yml matrix, but no reason to wait for that). 2. Replace the unpinned bootstrap install with a pinned tarball download. The prior 'curl https://git.io/misspell | sh' pattern executed a shell script from the master branch of an external repo via a git.io redirect — a supply-chain risk that also made CI non-reproducible. Now we download a specific release artifact (v0.3.4) directly from GitHub releases. 3. Verify the tarball SHA256 against the published checksum 'afd95caf1eecc72ff382791e00b3b11523a20b0579d95e2295c1c043688743d5' (linux_64bit). Any tampering or unexpected upstream change will fail CI rather than silently execute. Scope of misspell unchanged: still scans .md, .txt, examples/**, all of lib/ (excluding json.hpp), and tests/**. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/spellcheck.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index 912594c61..eeedb9c62 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml @@ -6,6 +6,12 @@ on: pull_request: branches: [ master, main ] +# Least-privilege GITHUB_TOKEN scope: misspell only reads .md/.txt files +# (no PR comments, no status updates, no package writes). Explicit block +# satisfies CodeQL "actions/missing-workflow-permissions" and keeps the +# token narrowly scoped if Actions analysis is enabled here later. +permissions: + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -22,9 +28,22 @@ jobs: continue-on-error: true - name: install misspell + env: + # misspell v0.3.4 linux 64-bit tarball SHA256 (from upstream + # release checksums.txt). Pinning version + verifying SHA + # avoids executing an unpinned bootstrap script from a floating + # ref (the prior 'curl https://git.io/misspell | sh' pattern is + # a supply-chain risk) and keeps CI reproducible. Bump + # deliberately when upstream releases. + MISSPELL_VERSION: "0.3.4" + MISSPELL_SHA256: "afd95caf1eecc72ff382791e00b3b11523a20b0579d95e2295c1c043688743d5" run: | - curl -L -o ./install-misspell.sh https://git.io/misspell - sh ./install-misspell.sh + curl -fsSL -o misspell.tar.gz \ + "https://github.com/client9/misspell/releases/download/v${MISSPELL_VERSION}/misspell_${MISSPELL_VERSION}_linux_64bit.tar.gz" + echo "${MISSPELL_SHA256} misspell.tar.gz" | sha256sum -c - + mkdir -p bin + tar -xzf misspell.tar.gz -C bin misspell + rm misspell.tar.gz - name: run misspell run: |