Describe the bug
The GitHub Actions workflows pin third-party actions by mutable tag (e.g.
@v4, @v2.7.8, @v5) rather than by immutable commit SHA. A compromised or
retargeted action tag would execute attacker-controlled code on CI runners during
push/PR. In code_coverage.yml the codecov/codecov-action step is additionally
handed the CODECOV_TOKEN secret.
Dependabot is configured for cargo only, so there is no automated tracking of
action-version updates.
To Reproduce
Source (pinned commit 9ad7b273e7f4c460d07feea0077b3a4491dcbc6a):
.github/workflows/ci.yml:23 and throughout: uses: actions/checkout@v4,
Swatinem/rust-cache@v2.7.8, extractions/setup-just@v3, etc. — all mutable tags.
.github/workflows/code_coverage.yml:29,34,49,55: actions/checkout@v4,
Swatinem/rust-cache@v2.7.8, actions/upload-artifact@v6, codecov/codecov-action@v5.
.github/workflows/code_coverage.yml:59: token: ${{ secrets.CODECOV_TOKEN }}.
.github/dependabot.yml:6: covers cargo, not github-actions.
Expected behavior
Pin every action to a full commit SHA, optionally with a trailing comment recording
the human-readable version, e.g.:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
and add a github-actions ecosystem entry to dependabot.yml so pinned SHAs are
kept current automatically.
Build environment
- Library: CI / supply chain (not a runtime library defect)
- Version/tag/commit:
9ad7b273e7f4c460d07feea0077b3a4491dcbc6a
- OS+version: GitHub-hosted runners
Additional context
- Impact class: CWE-829 (Inclusion of Functionality from Untrusted Control Sphere).
- Severity assessed as low after cross-model review: the only secret in scope is
CODECOV_TOKEN (a coverage-upload token); there are no release/publish workflows
or deploy credentials; runners are ephemeral; and ci.yml already runs on
pull_request, so arbitrary PR code already executes in the same runner class.
This is a supply-chain hardening opportunity, not an active exposure.
- Prior art for the risk class: the 2021 Codecov breach, where a modified uploader
exfiltrated CI secrets.
- Found during a security audit.
Describe the bug
The GitHub Actions workflows pin third-party actions by mutable tag (e.g.
@v4,@v2.7.8,@v5) rather than by immutable commit SHA. A compromised orretargeted action tag would execute attacker-controlled code on CI runners during
push/PR. In
code_coverage.ymlthecodecov/codecov-actionstep is additionallyhanded the
CODECOV_TOKENsecret.Dependabot is configured for
cargoonly, so there is no automated tracking ofaction-version updates.
To Reproduce
Source (pinned commit
9ad7b273e7f4c460d07feea0077b3a4491dcbc6a):.github/workflows/ci.yml:23and throughout:uses: actions/checkout@v4,Swatinem/rust-cache@v2.7.8,extractions/setup-just@v3, etc. — all mutable tags..github/workflows/code_coverage.yml:29,34,49,55:actions/checkout@v4,Swatinem/rust-cache@v2.7.8,actions/upload-artifact@v6,codecov/codecov-action@v5..github/workflows/code_coverage.yml:59:token: ${{ secrets.CODECOV_TOKEN }}..github/dependabot.yml:6: coverscargo, notgithub-actions.Expected behavior
Pin every action to a full commit SHA, optionally with a trailing comment recording
the human-readable version, e.g.:
and add a
github-actionsecosystem entry todependabot.ymlso pinned SHAs arekept current automatically.
Build environment
9ad7b273e7f4c460d07feea0077b3a4491dcbc6aAdditional context
CODECOV_TOKEN(a coverage-upload token); there are no release/publish workflowsor deploy credentials; runners are ephemeral; and
ci.ymlalready runs onpull_request, so arbitrary PR code already executes in the same runner class.This is a supply-chain hardening opportunity, not an active exposure.
exfiltrated CI secrets.