In August 2024, researchers from Palo Alto Networks' Unit 42 published a detailed analysis of artifact poisoning attacks targeting GitHub Actions workflows. The research demonstrated how attackers could inject malicious code into CI/CD pipelines by exploiting the way GitHub Actions handles artifacts, specifically the actions/upload-artifact and actions/download-artifact actions.
This is not a vulnerability in GitHub itself. It is an exploitation of trust assumptions that are baked into how many open-source projects and enterprises structure their CI/CD workflows.
How GitHub Actions Artifacts Work
GitHub Actions artifacts are files produced by one workflow job and consumed by another. Common use cases include:
- Building a binary in one job and running tests against it in another.
- Generating code coverage reports in a build job and publishing them in a deployment job.
- Producing release assets in a CI job and uploading them to a package registry in a CD job.
Artifacts are stored by GitHub and associated with a specific workflow run. They can be shared between jobs within the same workflow or downloaded by other workflows in the same repository.
The critical security assumption is that artifacts produced by your own workflows are trustworthy. This assumption breaks in several scenarios.
The Attack Vectors
Vector 1: Pull Request Artifact Injection
Many open-source projects use a two-stage CI process. The first stage runs in the context of the pull request (with limited permissions). The second stage, triggered by a separate workflow, processes the artifacts from the first stage with elevated permissions.
The classic example is the pull_request_target pattern. A workflow triggered by pull_request builds and tests the PR code. A separate workflow, running with write permissions and access to repository secrets, downloads the artifacts from the PR workflow to perform deployment or publishing.
If an attacker submits a malicious pull request that modifies the build process to inject code into the artifacts, the second-stage workflow will execute that code with elevated permissions. The attacker's code runs in a context that has access to repository secrets, deployment tokens, and write access to the repository.
Vector 2: Artifact Name Collision
GitHub Actions artifacts within a workflow run are identified by name. If multiple jobs in a workflow upload artifacts with the same name, the later upload overwrites the earlier one. An attacker who can trigger a workflow run (for example, by opening a pull request) may be able to race against a legitimate job to upload a malicious artifact with the same name.
Additionally, the actions/download-artifact action, in versions prior to v4, would download all artifacts from a workflow run if no specific artifact name was specified. This meant that an attacker who could upload any artifact to a workflow run could potentially inject files that would be consumed by downstream jobs.
Vector 3: Cross-Workflow Artifact Consumption
Some repository configurations allow workflows to consume artifacts from other workflows using the GitHub API. If the consuming workflow does not validate the source of the artifact (checking the workflow ID, commit SHA, and actor), an attacker who can trigger any workflow in the repository may be able to produce artifacts that are consumed by a more privileged workflow.
Real-World Impact
Unit 42 identified multiple high-profile open-source projects with vulnerable workflow configurations. While specific project names were disclosed responsibly and many have since been patched, the patterns are widespread:
- Projects that use artifact passing between
pull_requestandpull_request_targetworkflows without validating artifact integrity. - Projects that download artifacts and immediately execute scripts or binaries from them without verification.
- Projects that use artifact-based deployment pipelines where the artifact content directly controls what gets published.
The researchers estimated that thousands of public repositories had workflow configurations susceptible to at least one variant of artifact poisoning.
In a particularly concerning scenario, researchers demonstrated that a compromised artifact in a popular GitHub Action itself could cascade to every workflow that uses that action, creating a supply chain attack with massive blast radius.
The Deeper Problem: CI/CD Trust Models
Artifact poisoning is a symptom of a broader issue: CI/CD systems have implicit trust models that do not match the threat landscape.
Most CI/CD platforms were designed around the assumption that the code in the repository and the workflows that process it are controlled by trusted parties. This assumption breaks when:
- Pull requests from external contributors trigger workflows.
- Workflows consume outputs from less-privileged contexts.
- Reusable workflows and composite actions create complex trust chains.
The result is that CI/CD pipelines have become one of the most fertile attack surfaces in the software supply chain. They have access to source code, build environments, signing keys, deployment credentials, and package registry tokens. A compromise at the CI/CD level can inject malicious code into released software without ever modifying the source code directly, making it extremely difficult to detect.
Defensive Measures
Pin action versions by SHA, not tag: Tags can be moved to point to different commits. Pinning by full commit SHA ensures you are running exactly the code you reviewed.
# Bad: tag can be moved
- uses: actions/upload-artifact@v4
# Good: pinned to specific commit
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
Validate artifact provenance: When downloading artifacts, verify the workflow run ID, commit SHA, and actor that produced them. Reject artifacts from unexpected sources.
Minimize artifact trust: Treat downloaded artifacts as untrusted input. Validate checksums, scan for unexpected files, and avoid executing downloaded artifacts directly. Use a sandboxed environment for any processing of artifact contents.
Restrict workflow permissions: Use the permissions key in workflow files to grant the minimum required permissions. Never grant write permissions to workflows triggered by external pull requests.
permissions:
contents: read
pull-requests: read
Use OIDC for deployment: Instead of storing long-lived deployment secrets in GitHub, use GitHub's OIDC provider to obtain short-lived tokens scoped to specific workflow runs. This limits the blast radius of a compromised workflow.
Separate build and deploy workflows: Ensure that deployment workflows require explicit approval and do not automatically consume artifacts from build workflows without validation.
Enable artifact attestation: GitHub's artifact attestation feature (launched in beta in 2024) allows you to create cryptographically signed provenance information for artifacts, making it possible to verify exactly how and where an artifact was produced.
The Bigger Picture
CI/CD pipeline attacks represent the industrialization of supply chain compromises. Instead of targeting individual developers or modifying source code directly, attackers are targeting the build and release infrastructure that turns source code into distributable software.
The SolarWinds Sunburst attack in 2020 was a build-system compromise. The Codecov bash uploader attack in 2021 was a CI/CD supply chain attack. The GitHub Actions artifact poisoning research in 2024 shows that the attack surface continues to expand.
Securing CI/CD pipelines requires treating them with the same rigor as production environments: least privilege, input validation, monitoring, and defense in depth.
How Safeguard.sh Helps
Safeguard.sh provides visibility and governance for your software build and release pipeline.
- CI/CD dependency tracking maps the actions, scripts, and tools consumed by your GitHub Actions workflows, identifying unpinned versions, vulnerable actions, and overly permissive configurations.
- Build provenance verification validates that software artifacts were produced by authorized pipelines, detecting tampering or unauthorized modifications in the build process.
- SBOM generation at build time captures a complete snapshot of every dependency and tool involved in producing your software, creating an auditable record of your supply chain.
- Policy gates enforce security requirements at each stage of your pipeline, ensuring that artifacts are validated before they are consumed by downstream processes.
Your CI/CD pipeline is your software supply chain. Securing it is not optional.