Skip to content

Commit 808bda9

Browse files
docs(blog): add Trivy supply chain attack response post (#19)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 67c8beb commit 808bda9

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: "Our Response to the Trivy Supply Chain Attack"
3+
date: 2026-03-23
4+
description: "How the Trivy GitHub Actions compromise affected DevRail, what we found, and what we changed."
5+
---
6+
7+
On March 19, 2026, attackers compromised credentials for the Aqua Security GitHub organization and force-pushed 75 of 76 version tags in the [trivy-action](https://github.com/aquasecurity/trivy-action) repository to point at malicious commits containing an infostealer. A malicious Trivy binary (v0.69.4) was also briefly published. This post covers our assessment and response.
8+
9+
## What Happened
10+
11+
The attackers exploited credentials that were not fully rotated after a prior incident on March 1. During a window of approximately 12 hours (March 19 ~17:43 UTC to March 20 ~05:40 UTC), every `trivy-action` tag from `0.0.1` through `0.34.0` pointed to a commit that ran a Python-based credential stealer. The payload harvested environment variables, SSH keys, cloud credentials, Kubernetes tokens, and other secrets from CI runners, then exfiltrated them to a command-and-control server.
12+
13+
Full details are available in [Aqua Security's advisory](https://github.com/aquasecurity/trivy/discussions/10425) and [aquasecurity/trivy-action#541](https://github.com/aquasecurity/trivy-action/issues/541).
14+
15+
## Impact on DevRail
16+
17+
**No DevRail secrets were compromised.**
18+
19+
Our CI workflow (`ci.yml`) referenced `aquasecurity/trivy-action@0.28.0`, which was among the hijacked tags. However, all CI runs on March 19 completed by 04:58 UTC -- approximately 13 hours before the attack window opened at ~17:43 UTC. No CI jobs ran during the compromise period.
20+
21+
The Trivy binary inside the dev-toolchain container (v0.69.3, installed via the APT repository at `get.trivy.dev/deb`) was not affected. The malicious binary was v0.69.4, which was published only via GitHub releases and Docker Hub, not the APT channel.
22+
23+
| Component | Our version | Status |
24+
|---|---|---|
25+
| Trivy binary in container | 0.69.3 (APT) | Not affected |
26+
| `trivy-action` in CI | `@0.28.0` (tag) | Tag was hijacked, but no runs during the window |
27+
| `setup-trivy` | Not used | N/A |
28+
29+
## What We Changed
30+
31+
We pinned `trivy-action` to a full commit SHA instead of a version tag:
32+
33+
```yaml
34+
# Before (vulnerable to tag poisoning)
35+
uses: aquasecurity/trivy-action@0.28.0
36+
37+
# After (immune to tag poisoning)
38+
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
39+
```
40+
41+
Version 0.35.0 was created after the first incident and was confirmed safe by Aqua Security.
42+
43+
This change is in [dev-toolchain PR #18](https://github.com/devrail-dev/dev-toolchain/pull/18).
44+
45+
## Lessons
46+
47+
**Pin GitHub Actions to commit SHAs, not version tags.** Git tags are mutable -- anyone with write access can force-push a tag to point at any commit. A compromised maintainer credential is enough to silently replace every version of an action with malicious code. SHA references are immutable and cannot be changed after the fact.
48+
49+
This applies to all third-party GitHub Actions, not just Trivy. The [GitHub documentation on security hardening](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions) recommends the same practice.
50+
51+
**Install tools from package managers when possible.** The Trivy binary inside our container was installed via APT, not from GitHub releases. The APT channel was not compromised. Package manager distribution adds a layer of indirection that makes supply chain attacks harder to execute -- the attacker would need to compromise the package repository infrastructure, not just a single GitHub credential.
52+
53+
**Monitor your CI execution windows.** Knowing exactly when your CI jobs ran relative to a compromise window is the difference between "rotate everything" and "no action needed." We were able to confirm no exposure because our run timestamps were well outside the attack period.

0 commit comments

Comments
 (0)