←Research
Researchsecurity10 min read

Trivy turned a security scanner into a credential stealer

The Trivy compromise showed why CI/CD security tools are high-value supply chain targets: they run where secrets, tokens and publishing credentials already live.

Trivy's March 2026 compromise turned a vulnerability scanner into a credential stealer. According to Aqua Security's advisory, a threat actor used compromised credentials on 19 March to publish a malicious Trivy v0.69.4 release, move 76 of 77 aquasecurity/trivy-action version tags to malicious commits and replace every aquasecurity/setup-trivy tag with attacker-controlled code.

That is not only another story about mutable Git tags. It is a cleaner illustration of a more awkward problem: security tooling often runs in the most credential-rich part of the software factory. A scanner in CI does not need to break into the build system. The build system invites it in, gives it repository access and surrounds it with the secrets needed to publish, deploy and administer infrastructure.

What Aqua says was compromised

Aqua's GitHub advisory breaks the incident into four exposure windows. The malicious Trivy v0.69.4 release was public for roughly three hours on 19 March 2026, from 18:22 UTC until about 21:42 UTC. The trivy-action tag hijack lasted roughly 12 hours, from about 17:43 UTC on 19 March until about 05:40 UTC on 20 March. The setup-trivy compromise lasted about four hours.

The attacker returned through a second distribution path on 22 March. Aqua says malicious Docker Hub images for aquasec/trivy:0.69.5 and aquasec/trivy:0.69.6 were pushed using separately compromised Docker Hub credentials. Those images were exposed for roughly ten hours, from 15:43 UTC on 22 March until about 01:40 UTC on 23 March.

The affected components were not obscure edge packages. Trivy is a widely used scanner for containers, filesystems, repositories, Kubernetes configurations and infrastructure-as-code. Its GitHub Action is the convenient way many projects embed that scanning into CI. setup-trivy installs the tool for workflows that want explicit setup. Those components sit exactly where attackers want to be: before release, near secrets and inside automation.

The advisory maps the incident to CVE-2026-33634 and CWE-506: Embedded Malicious Code. CISA added it to the Known Exploited Vulnerabilities catalogue on 26 March, describing a compromise that could expose "everything in the CI/CD environment", including tokens, SSH keys, cloud credentials, database passwords and sensitive configuration in memory.

The payload ran before the scanner

The compromised trivy-action did not replace scanning with an obvious failure. Aqua says the malicious code ran before the legitimate Trivy scan and injected an infostealer into entrypoint.sh. That sequencing matters. A workflow owner may still see a scan run and assume the action behaved normally. The theft happens in the prelude.

Aqua's advisory says the payload dumped Runner.Worker process memory through /proc/<pid>/mem to extract secrets, then swept more than 50 filesystem locations for useful material: SSH keys, AWS, GCP and Azure credentials, Kubernetes tokens, Docker configuration files, .env files, database credentials and cryptocurrency wallets. The collected data was encrypted with AES-256-CBC and RSA-4096 hybrid encryption before being sent to attacker-controlled infrastructure.

There was also a fallback exfiltration path. If direct exfiltration failed and INPUT_GITHUB_PAT was set, the malware attempted to create a public repository named tpcp-docs in the victim's GitHub account and upload the stolen bundle as a release asset. Aqua's remediation guidance specifically tells organisations to search their GitHub organisations for repositories with that name.

This is why the incident is worse than a bad release tag. The payload targeted the CI runner as an environment, not Trivy as a product. The scanner was the delivery vehicle. The prize was the trust boundary around the pipeline.

The release path was also poisoned

The malicious Trivy v0.69.4 release took a separate route. Aqua says the attacker pushed a commit that changed the actions/checkout reference to an imposter commit containing a composite action. That action downloaded malicious Go source files from a typosquatted domain. The attacker also added --skip=validate to GoReleaser to bypass binary validation, then tagged the commit as v0.69.4 to trigger the release pipeline.

That released malicious artefacts through normal distribution channels: GitHub releases, container registries, Debian and RPM packages and get.trivy.dev. In other words, the compromise did not rely on users doing something unusual. It relied on users consuming the latest release of a trusted security tool through ordinary paths.

Aqua says the malicious code was not committed to Trivy's main branch. It was fetched and built on an ephemeral runner. That detail is important for responders because source review of main would not explain the distributed artefact. The boundary between repository source and release artefact is where the attack lived.

The Docker Hub follow-on is a useful warning against assuming one registry tells the whole story. Aqua says v0.69.5 and v0.69.6 Docker Hub images were pushed directly with separate Docker Hub credentials, with no corresponding GitHub tags or releases. A user checking GitHub alone could still miss exposure through Docker Hub.

The awkward remediation lesson

Aqua's root-cause section is the part defenders should read twice. The advisory says the March incident was a continuation of a supply chain attack that began in late February 2026. After the initial disclosure on 1 March, credential rotation was performed, but not atomically. Not every credential was revoked at the same time. Aqua says the attacker could have used a still-valid token to exfiltrate newly rotated secrets during the rotation window, which lasted a few days. That may have allowed the attacker to retain access and execute the 19 March attack.

That is the lesson most post-incident advice flattens into "rotate your secrets". Rotation is not a ritual. If the old access remains alive while new credentials are being introduced, rotation can become a secret refresh service for the attacker. The order matters. The revocation boundary matters. The audit trail matters. So does proving that every path using the old credential has actually lost access.

This is especially hard in CI/CD because credentials are scattered across repository secrets, organisation secrets, environment variables, cloud IAM roles, registry tokens, package publishing credentials, GitHub Apps and personal access tokens. Some are long-lived. Some are inherited. Some are mounted into jobs indirectly. Some are copied into third-party tooling because a pipeline once needed to ship on a Friday.

The Trivy advisory makes that mess visible. The attacker did not need a theoretical zero-day in CI. They needed retained access in the machinery that publishes and runs trusted tooling.

Mutable tags made the blast radius wider

The tag hijack still matters. GitHub Actions references such as aquasecurity/trivy-action@0.34.0 feel like version pinning, but they are only as stable as the tag. If the tag moves, the workflow follows it. Aqua says 76 of 77 trivy-action tags were force-pushed to malicious commits. All seven setup-trivy tags from v0.2.0 through v0.2.6 were also replaced.

GitHub's own secure use guidance recommends pinning third-party actions to full commit SHAs. That advice is old, correct and widely ignored because version tags are readable and SHAs are not. The Trivy compromise is the bill for that convenience.

There is a nuance here. SHA pinning is not magic. Aqua notes that a workflow pinned to an old trivy-action commit before April 2025 could still invoke a compromised setup-trivy during the setup-trivy exposure window, depending on how it installed Trivy. Pinning reduces one mutable reference. It does not remove every transitive runtime decision inside the action.

Still, the direction is clear. Version tags are a release-management affordance, not a security boundary. If a third-party action receives secrets, publishes artefacts or runs in a privileged job, a moving tag is not a serious control.

What safe looked like

Aqua lists known safe versions rather than asking users to reason from memory. For Trivy binary and image usage, v0.69.2 and v0.69.3 are known safe. Version v0.69.3 was protected by GitHub's immutable releases feature before publication, while v0.69.2 can be checked with sigstore signatures. For trivy-action, the safe version is v0.35.0. For setup-trivy, Aqua recreated v0.2.6 with safe content.

The incident response steps are blunt because they have to be. If a compromised version may have run, assume every secret accessible to that pipeline was exposed. Audit Trivy versions and remove affected artefacts. Review workflows using aquasecurity/trivy-action and aquasecurity/setup-trivy. Check workflow logs from 19 to 20 March for affected action references. Search for tpcp-docs repositories. Rotate accessible secrets, not only the one token that looks directly related.

CISA's KEV entry required covered organisations to apply vendor mitigations or discontinue use by 9 April 2026. That deadline is less interesting than the wording. CISA described the vulnerable component as a supply chain compromise in a product that may be used across multiple products and environments. That is the real blast radius shape. One scanner can sit behind many releases.

Do not overfit on attribution

Several vendor writeups discuss the Trivy incident in the context of the wider TeamPCP campaign. Wiz's reporting on the related KICS GitHub Action compromise is useful campaign context, particularly because the same class of CI/CD security tooling was targeted. Snyk's Trivy analysis also frames the incident as part of a broader supply chain sequence.

The primary Aqua advisory, however, uses "threat actor" rather than making a strong public attribution. That distinction should survive into the analysis. Attribution can help defenders connect infrastructure and tradecraft, but it should not become a decorative label slapped onto an incident because it makes the story neater.

The more defensible claim is structural: whoever ran the operation understood that security tools have privileged access to secrets and publishing paths. That is enough. Names are useful. Access paths are what need fixing.

The scanner is now part of the attack surface

Security teams like scanners because they turn risk into tickets. That is useful, but it has encouraged a habit of treating scanners as passive observers. They are not. A scanner in CI is executable third-party code running beside source, build credentials, registry access, cloud credentials and sometimes deployment authority. It is a dependency with a badge and a better threat model on the sales page.

Palo Alto Networks' analysis uses the right framing: a security scanner became the weapon. The phrase is slightly vendor-blog shiny, but the underlying point is correct. Defensive tooling is software supply chain surface. The fact that it is installed for security does not make it safe by category.

The better control set starts with reducing what CI jobs expose. A scan job should not inherit production deployment credentials because another job in the same workflow needs them later. Third-party actions should run in the least privileged context that still lets them do their job. Package publishing tokens should not be available to jobs that only need to inspect source. Long-lived personal access tokens should be hunted to extinction with the grim enthusiasm they deserve.

Then come the integrity controls: pin third-party actions to full commit SHAs, prefer signed and reproducible release artefacts, verify container images by digest where possible and watch for drift between source tags and published artefacts. None of these controls is sufficient alone. Together they force the attacker to compromise more than one convenient hinge.

The trust boundary moved

The Trivy compromise is not important because one scanner had a bad week. It is important because it shows how modern supply chain attacks choose their targets. The most valuable software is not always the software with the most users. It is the software that runs where the credentials are.

That makes CI/CD security tooling attractive in a way defenders have not fully internalised. Scanners, linters, release helpers, setup actions and deployment utilities are often waved through because they are part of the machinery that proves everything else is safe. The Trivy incident is a reminder that the machinery is also code. It can be tagged, moved, poisoned, rebuilt and distributed like everything else.

The uncomfortable lesson is that "security tool" is not a trust tier. It is an access request.

Newsletter

One email a week. Security research, engineering deep-dives and AI security insights - written for practitioners. No noise.