Skip to content

Harden GitHub Actions workflow (PSIRT-0328599349)#59

Merged
yogsototh merged 2 commits into
masterfrom
harden-actions-psirt-0328599349
Jun 16, 2026
Merged

Harden GitHub Actions workflow (PSIRT-0328599349)#59
yogsototh merged 2 commits into
masterfrom
harden-actions-psirt-0328599349

Conversation

@yogsototh

Copy link
Copy Markdown
Contributor

Summary

Hardens .github/workflows/build.yml against the GitHub Actions vulnerability classes flagged by PSIRT-0328599349 (advisory: "GitHub Actions associated with threatgrid/flanders may contain vulnerabilities").

Two changes, both standard CI supply-chain hardening:

  • Pin all actions to full commit SHAs (with a version comment). Mutable version tags (@v4, @3.7, ...) let a retagged or compromised upstream release execute arbitrary code in CI. The primary exposure was the third-party action DeLaGuardo/setup-clojure; the actions/* steps are pinned as well.
  • Add least-privilege token permissions -- a top-level permissions: contents: read block. Previously the workflow inherited the repo/org default GITHUB_TOKEN scope. This job set only builds, lints and tests; it performs no writes (deploy to Clojars is a manual lein task, not CI-driven), so read-only is sufficient.

Verified vulnerability classes

  • Unpinned third-party / first-party actions -- FIXED (this PR).
  • Broad default token permissions -- FIXED (this PR).
  • pull_request_target checking out untrusted code -- not present.
  • Script injection via ${{ github.event.* }} in run: steps -- not present.
  • Secrets exposed to fork PRs -- not present (no secrets referenced in CI).

No behavior change

Each pinned SHA is the current tip of the version previously referenced:

  • actions/checkout -> 34e1148 (v4.3.1)
  • actions/cache -> 0057852 (v4.3.0) and 6f8efc2 (v3.5.0)
  • actions/setup-java -> 17f84c3 (v3.14.1) and 91d3aa4 (v2.5.1)
  • DeLaGuardo/setup-clojure -> fa52269 (3.7) and 0fc99a3 (12.1)

Follow-up (not in this PR)

  • A .github/dependabot.yml with package-ecosystem: github-actions would keep these SHAs updated automatically.
  • The deprecated ::set-output usage (line ~47) should move to $GITHUB_OUTPUT; left out here to keep the diff security-scoped.

Context

threatgrid/flanders is consumed by IROH as a dependency (iroh/project.clj: [threatgrid/flanders "1.1.0"]). This PR is filed as remediation for the PSIRT advisory; the CTIM library maintainers should confirm the version pins.

🤖 Generated with Claude Code

Pin all actions to full commit SHAs and apply least-privilege token
permissions, addressing the GitHub Actions vulnerability classes flagged
by PSIRT-0328599349.

- Pin every `uses:` to a commit SHA with a version comment, so a
  retagged or compromised upstream release cannot inject code into CI.
  This covers the third-party action DeLaGuardo/setup-clojure (the main
  supply-chain exposure) as well as the actions/* steps.
- Add a top-level `permissions: contents: read` block so the default
  GITHUB_TOKEN is least-privilege. The workflow only builds, lints and
  tests; it performs no writes (deploy to Clojars is a manual lein task,
  not CI-driven).

No behavior change: each SHA is the current tip of the version that was
previously referenced (checkout v4.3.1, cache v4.3.0/v3.5.0,
setup-java v3.14.1/v2.5.1, setup-clojure 3.7/12.1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@yogsototh yogsototh self-assigned this Jun 16, 2026
@yogsototh yogsototh requested review from ereteog and msprunck June 16, 2026 09:47

@msprunck msprunck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

The Build workflow was auto-disabled (disabled_inactivity) after 60+ days
idle, so the required 'all-pr-checks' status never ran on this PR. Re-enabled
the workflow; this empty commit re-fires the pull_request run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@yogsototh yogsototh merged commit 598bf37 into master Jun 16, 2026
6 checks passed
yogsototh added a commit that referenced this pull request Jun 16, 2026
#60)

Follow-up to #59, addressing the remaining findings from the PSIRT
review of build.yml.

- Replace the deprecated `::set-output` command with the `$GITHUB_OUTPUT`
  environment file in the setup job's set-matrix step. GitHub deprecated
  `::set-output` citing output-injection concerns; the environment file
  is the supported, safer mechanism. Also fixes a stray trailing `}` in
  the emitted JSON (`...["test"]}}` -> `...["test"]}`).
- Remove `eval` from the test job's run step. `eval 'lein ... ${CMD}'`
  re-parsed a matrix-derived variable through the shell; passing it as a
  normal quoted argument (`lein do clean, compile :all, "$CMD"`) removes
  the eval/command-injection anti-pattern.

No behavior change: `matrix.cmd` is hardcoded to `test`, so both jobs run
exactly as before (the matrix output is still consumed via
`needs.setup.outputs.matrix`).

Not in this PR: bumping action major versions (setup-java v2->v4,
cache v3->v4) is a runtime-behavior change better handled by Dependabot;
the actions are already SHA-pinned as of #59.

Co-authored-by: Yann Esposito (Yogsototh) <guillaume@ereteo.net>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants