GitHub Actions Supply Chain Attacks in 2025: Poisoned Caches, Artifact Tampering and OIDC Token Theft
Cloud Security
CI/CD pipelines are the new malware delivery mechanism. This post covers three active GitHub Actions attack patterns from 2025 red team engagements — poisoned cache injection, artifact checksum bypass, and OIDC token exfiltration — with detection and hardening guidance.
By Arjun Raghavan, Security & Systems Lead, BIPI · September 5, 2025 · 11 min read
The xz backdoor in 2024 was a warning shot. The npm worm wave in early 2025 was the follow-through. Both demonstrated the same principle: the software supply chain is now a primary attack vector, and CI/CD pipelines are the most direct path from a malicious commit to a production deployment. GitHub Actions, which runs the majority of open-source and many enterprise CI/CD pipelines, is a high-value target.
Supply chain attacks on GitHub Actions take three main forms in 2025. Poisoned caches exploit the actions/cache mechanism to inject malicious binaries that persist across workflow runs. Artifact tampering replaces build outputs between jobs. OIDC token theft abuses the federated identity mechanism to obtain cloud credentials without storing secrets in the repository.
OIDC token theft is the most underestimated GitHub Actions attack vector. The token never touches disk, leaves no secret in the repo, and is valid for the duration of the workflow run.
Attack 1 — poisoned cache injection
The actions/cache action stores and restores cached files keyed by a cache key string. Cache keys are often deterministic and predictable — for example, a hash of the package-lock.json file. An attacker who can open a pull request from a fork can calculate the same cache key and pre-seed the cache with a malicious entry before the main branch workflow runs. When the legitimate workflow restores the cache, it retrieves the poisoned version.
This attack is particularly effective for compiled dependencies and tool binaries cached in CI. The malicious binary runs with the full privileges of the workflow, including access to secrets and OIDC tokens. The cache entry persists until explicitly evicted or until it expires, meaning the attack can re-trigger on every subsequent workflow run.
- Mitigation: use cache keys that include a secret or non-predictable component the PR author cannot calculate.
- Mitigation: verify cached binaries against pinned checksums before execution.
- Mitigation: restrict cache write access to the main branch only using environment protection rules.
- Detection: alert on cache key collisions and unexpected cache restore events from fork PRs.
Attack 2 — artifact tampering between jobs
GitHub Actions workflows frequently pass build artifacts between jobs using upload-artifact and download-artifact. Artifacts are stored server-side and accessible to any job in the same workflow run. An attacker who has compromised one job in a workflow can overwrite the artifact with a tampered binary that the subsequent deployment job will fetch and deploy.
The root cause is that artifact integrity is not verified by default. The deployment job trusts that the artifact matches what the build job produced. Implementing SLSA Level 2 or higher addresses this by generating a signed provenance attestation that the deployment job verifies before proceeding.
Attack 3 — OIDC token exfiltration
GitHub Actions OIDC tokens allow workflows to authenticate to cloud providers without storing credentials as secrets. The workflow calls the OIDC token endpoint and receives a short-lived JWT that it exchanges for cloud credentials. The problem is that any step in the workflow can request the OIDC token, including a malicious action injected via a compromised dependency.
Once an attacker has the OIDC token, they can exchange it for cloud credentials outside the workflow context. The cloud provider's OIDC federation policy controls what the token can do, but many organizations grant overly broad permissions to their GitHub OIDC provider. We have seen OIDC token theft pivot directly to S3 bucket access, ECR image push, and Terraform state read.
- Pin every third-party action by full SHA, not by tag or major version.
- Use id-token: write permission only in the specific job that needs OIDC, not at the workflow level.
- Scope the cloud IAM role to the specific repository and branch using the sub claim condition in the trust policy.
- Enable GitHub artifact attestation and verify attestations in deployment workflows.
- Use the Sigstore/cosign action to sign and verify images as part of the build pipeline.
Workflow hardening baseline
Every workflow should have permissions: read-all at the top and override upward only for the specific job that needs write access. Default-deny is the right stance. Review every uses: statement in your workflows and replace tags with SHAs. Dependabot can automate SHA updates for pinned actions.
Detection signals in GitHub audit logs
- workflow_run events where the triggering workflow is from a fork and accesses cache keys from the main branch.
- actions.oidc.token events for repositories or branches that should not be requesting OIDC tokens.
- Artifact download events from jobs that are not the designated deployment job in the workflow.
- Unexpected changes to workflow YAML files in PRs from non-team members.
Closing
GitHub Actions security is still treated as an afterthought in most organizations. The same teams that have rigorous code review processes merge workflow changes without security review, use mutable action tags, and grant OIDC tokens workflow-wide. The attacks described here are not theoretical — they are patterns we document in red team reports and that appear in public incident disclosures. Treat your workflow YAML files as security-critical infrastructure.
Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.