Skip to content

ci: pin third-party Actions to commit SHAs (CWE-829)#1040

Open
GaltRanch wants to merge 1 commit into
nasa:devfrom
GaltRanch:sec/pin-third-party-actions-to-sha
Open

ci: pin third-party Actions to commit SHAs (CWE-829)#1040
GaltRanch wants to merge 1 commit into
nasa:devfrom
GaltRanch:sec/pin-third-party-actions-to-sha

Conversation

@GaltRanch
Copy link
Copy Markdown

Summary

Pin third-party GitHub Actions in the main .github/workflows/ of the
cFS bundle to immutable 40-character commit SHAs, addressing
CWE-829: Inclusion of Functionality from Untrusted Control Sphere.

This PR covers 10 pinnings in the cFS main repo. Submodules
(cfe/, osal/, tools/eds/) have separate workflow files; analogous
PRs against those repositories will follow.

Why

Third-party Actions pinned to mutable tags (@v2, @master, etc.)
execute whatever the upstream maintainer pushes to that ref at workflow
run time. A maintainer compromise or a tag rewrite causes the action to
run attacker code with ${{ secrets.* }} in scope.

The March 2025 tj-actions/changed-files supply-chain incident
(CVE-2025-30066) was
exactly this shape: 23,000+ workflows compromised because they used
@v45 instead of a SHA. GitHub's hardening guidance explicitly
recommends SHA pinning for third-party Actions:
Security hardening for GitHub Actions — using third-party actions.

Changes (10 pinnings across 7 workflow files)

File:Line Action Was Now
build-doc-reusable.yml:56 fkirc/skip-duplicate-actions @master @<sha> # master
build-run-app-reusable.yml:49 fkirc/skip-duplicate-actions @master @<sha> # master
changelog.yml:21 heinrichreimer/github-changelog-generator-action @v2.1.1 @<sha> # v2.1.1
codeql-reusable.yml:77 fkirc/skip-duplicate-actions @master @<sha> # master
codeql-reusable.yml:167 advanced-security/filter-sarif @v1 @<sha> # v1
format-check.yml:26 fkirc/skip-duplicate-actions @master @<sha> # master
format-check.yml:77 gsactions/commit-message-checker @v2 @<sha> # v2
mcdc-reusable.yml:36 fkirc/skip-duplicate-actions @master @<sha> # master
mcdc-reusable.yml:148 dawidd6/action-download-artifact @v2 @<sha> # v2
unit-test-coverage-reusable.yml:44 fkirc/skip-duplicate-actions @master @<sha> # master

Each SHA was resolved via gh api against the tag/branch previously in
use. The human-readable ref is preserved as a # <ref> comment so future
Dependabot bumps and human reviewers can see the intended version.

@master pins are particularly risky (branch HEAD moves on every push)
— those are the highest-priority ones in this batch.

Submodule follow-ups (separate PRs to come)

5 additional findings in submodule workflows that need their own PRs:

  • cfe/.github/workflows/mcdc.yml:149 (nasa/cFE)
  • osal/.github/workflows/build-osal-documentation.yml:25 (nasa/osal)
  • osal/.github/workflows/mcdc.yml:34 (nasa/osal)
  • osal/.github/workflows/mcdc.yml:144 (nasa/osal)
  • tools/eds/.github/workflows/validation-test.yml:32 (nasa/eds)

Test plan

  • CI workflows still run successfully against the pinned SHAs.
  • Action behavior is identical (pinned SHAs correspond to the
    tag/branch HEADs previously in use).

Provenance

Discovered by Kulvex Code (KCode),
a deterministic SAST scanner. Pattern: cloud-006-gha-third-party-no-sha.

Per common AI-assist disclosure practice: AI tooling was used. Discovery
via KCode (deterministic regex+AST patterns + LLM verifier). Fix generation
via KCode agentic mode (Grok 4.2 reasoning + Claude Sonnet 4.5 fallback).
Each SHA resolution was done by gh api calls, not invented.

— Bruno Aiub · AstroLexis · Kulvex Code · contact@astrolexis.space

Signed-off-by: GaltRanch <bruno@nexocore.uy>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants