Skip to main content
75 GitHub Action Tags Hijacked in Trivy Supply Chain AttackIncident
5 min readFor Security Engineers

75 GitHub Action Tags Hijacked in Trivy Supply Chain Attack

On a recent weekend, attackers rewrote nearly every version tag in the aquasecurity/trivy-action repository. Within hours, CI/CD pipelines across hundreds of organizations were executing malicious code instead of the vulnerability scanner they trusted. The attackers' goal was to exfiltrate secrets from GitHub Actions workflows.

This wasn't a sophisticated zero-day exploit. It was a credentials compromise that allowed attackers to force-push to 75 out of 76 version tags, replacing legitimate scanner code with a payload designed to steal environment variables, tokens, and API keys from running workflows.

What Happened

Attackers gained access to credentials with sufficient privileges to modify the aquasecurity/trivy-action GitHub repository. They used these credentials to force-push malicious code to existing version tags—a technique that bypasses typical branch protection rules because tags are treated differently than branches in Git.

The malicious payload targeted GitHub Actions workflows specifically. When a workflow referenced a compromised tag (like v0.24.0), it executed the attacker's code instead of the legitimate Trivy scanner. That code collected secrets from the workflow environment and transmitted them to attacker-controlled infrastructure.

Aqua Security, which maintains Trivy, detected the compromise and revoked the affected credentials. They regenerated all tags from known-good commits and published guidance for users to verify their workflows hadn't executed the malicious versions.

Timeline

Initial compromise: Attackers obtained credentials with push access to the repository. The exact timeline of credential theft remains unclear.

Attack execution: 75 version tags were force-pushed with malicious payloads. The attack targeted the GitHub Actions integration specifically, leaving the main Trivy CLI tool unaffected.

Detection: Aqua Security's security team identified unauthorized changes to repository tags.

Response: Compromised credentials were revoked, all tags were regenerated from verified commits, and public notification was issued.

Second incident: This marked the second compromise of Trivy infrastructure in a short period, though the mechanisms differed between incidents.

Which Controls Failed

Credential rotation and lifecycle management: The compromised credentials had remained valid long enough for attackers to plan and execute a coordinated attack against 75 tags. Organizations often grant long-lived credentials to automation systems without implementing rotation schedules.

Tag protection: GitHub repositories typically enforce branch protection rules but leave tags unprotected. The attackers exploited this gap—force-pushing to tags doesn't trigger the same review requirements as pushing to protected branches.

Workflow dependency pinning: Organizations referencing tags by name (like @v0.24.0) rather than immutable commit SHAs meant their workflows automatically pulled the compromised code. There was no human review step when the underlying code behind the tag changed.

Secrets exposure in CI/CD: The attack succeeded because GitHub Actions workflows had access to sensitive credentials in their environment. Even when the malicious code executed, proper secrets management could have limited the blast radius.

Privilege scoping: The compromised credentials had write access to tags across the entire repository. More granular permissions could have prevented or limited the attack's scope.

What the Standards Require

NIST 800-53 Rev 5 Requirement IA-5(1) addresses authenticator management: "The organization manages system authenticators by... (e) changing default authenticators upon system installation; (f) establishing minimum and maximum lifetime restrictions and reuse conditions for authenticators." The compromised credentials violated lifetime restrictions—they remained valid without rotation.

ISO/IEC 27001 Annex A.5.15 (Access Control) and A.8.3 (Information Security in Supplier Relationships) require organizations to control access to information assets and manage security in supplier relationships. When you consume open-source actions, you're creating a supplier relationship that requires security controls.

PCI DSS Requirement 6.3.2 states: "An inventory of bespoke and custom software, and third-party software components incorporated into bespoke and custom software is maintained to facilitate vulnerability and patch management." Your GitHub Actions workflows are custom software, and the actions they reference are third-party components requiring inventory and management.

SOC 2 CC6.1 (Logical and Physical Access Controls) requires entities to implement logical access security measures to protect against threats from sources outside its system boundaries. Your CI/CD pipeline is within your system boundary—the actions it executes are outside it.

Lessons and Action Items

Pin GitHub Actions to commit SHAs, not tags: Update every workflow file in your repositories. Change uses: aquasecurity/[email protected] to uses: aquasecurity/trivy-action@a1b2c3d... (the full 40-character SHA). This prevents tag rewrites from affecting your workflows. Yes, it makes updates more deliberate—that's the point.

Implement tag protection: GitHub now offers tag protection rules. Enable them for your repositories, especially those containing actions or shared workflows. Require pull request reviews before anyone can create or modify tags.

Audit your action dependencies today: Run this command in each repository: grep -r "uses:" .github/workflows/. For every action you reference, verify it's pinned to a SHA. Document which actions have access to which secrets. Remove any secrets that aren't strictly necessary for the action to function.

Rotate credentials on a schedule: Every credential with write access to your repositories needs a maximum lifetime. Set a 90-day rotation schedule for service accounts and automation credentials. Your CI/CD platform should support this—if it doesn't, that's a vendor selection issue.

Minimize secrets in workflow environments: Use OIDC federation instead of long-lived credentials where possible. When workflows need cloud access, use GitHub's OIDC provider to obtain short-lived tokens. For other secrets, use environment-specific secrets and restrict them to specific branches or tags.

Monitor for force-pushes: Configure alerts for force-pushes to protected branches and tags. In GitHub, you can use the audit log API to track these events. A force-push to a tag in a repository you don't control should trigger immediate investigation.

Verify action sources before first use: Before adding a new action to your workflows, check the repository's security posture. Look for: active maintenance, security policy, signed commits, and whether the organization has published security advisories for past incidents. Two compromises in quick succession is a pattern.

The Trivy incident demonstrates that supply chain security isn't about sophisticated attacks—it's about basic credential hygiene and dependency management. The attackers didn't exploit a vulnerability in GitHub Actions. They used legitimate credentials to modify code that your workflows trusted by default.

Your action items start with an audit. Tomorrow morning, generate a list of every GitHub Action your organization uses. By the end of the week, pin them all to SHAs and document your rotation schedule for credentials with repository access. This isn't theoretical hardening—it's responding to an attack pattern that's now been proven effective twice against the same target.

Topics:Incident

You Might Also Like