特里维生态系统供应链短暂受损
Trivy ecosystem supply chain briefly compromised

原始链接: https://github.com/aquasecurity/trivy/security/advisories/GHSA-69fq-xp46-6x23

## Trivy 供应链攻击总结 (2026年3月) 2026年3月19日,一名恶意行为者利用先前泄露的凭据发起针对Trivy漏洞扫描器及其相关GitHub Actions的供应链攻击。攻击者发布了恶意Trivy v0.69.4版本,劫持了`aquasecurity/trivy-action`中的76个标签中的77个,并将`aquasecurity/setup-trivy`中的所有7个标签替换为包含窃取信息的恶意提交。 根本原因是在二月底不完整的凭据轮换,导致攻击者在轮换窗口期间保留了访问权限。该恶意软件会从GitHub Actions runner环境中窃取密钥(SSH密钥、云凭据等),对其进行加密,并尝试将其泄露。如果泄露失败,它将在受害者的GitHub帐户上创建一个公共仓库来存储被盗数据。 **受影响版本:** Trivy v0.69.4,`trivy-action`(所有标签,最高至0.34.2),以及`setup-trivy`(v0.2.0 – v0.2.6)。 **缓解措施:** 更新至Trivy v0.69.2或v0.69.3,`trivy-action` v0.35.0,或`setup-trivy` v0.2.6。**至关重要的是,轮换所有可能泄露的密钥,并使用完整的commit SHA哈希值固定GitHub Actions**,以防止未来劫持标签。使用提供的sigstore签名验证安装。

## Trivy 供应链攻击 - 摘要 Trivy,一款流行的漏洞扫描器,最近再次遭受供应链攻击,源于先前未充分解决的安全事件。 这不是 Trivy 代码本身的妥协,而是直接攻击 Aqua Security 控制下的 Trivy 组件。 攻击涉及将恶意入口点注入到受影响的标签中,可能使攻击者能够访问凭证和 CI/CD 管道。 虽然哈希固定可以减轻一些风险,但它不是一个完整的解决方案,因为操作仍然可以拉取可变依赖项。 该事件凸显了信任安全工具的固有风险,这些工具通常以高权限运行。 讨论的重点是改进凭证管理(原子轮换)、在事件发生后进行更严格的风险重新评估,以及将固定点定位到特定的 commit SHA 而不是可变标签的重要性。 此次攻击导致进一步的妥协,包括传播到 npm 包,这表明问题的严重性和持续性。
相关文章

原文

Summary

On March 19, 2026, a threat actor used compromised credentials to publish a malicious Trivy v0.69.4 release, force-push 76 of 77 version tags in aquasecurity/trivy-action to credential-stealing malware, and replace all 7 tags in aquasecurity/setup-trivy with malicious commits.

Root Cause

This incident is a continuation of the supply chain attack that began in late February 2026. Following the initial disclosure on March 1, credential rotation was performed but was not atomic (not all credentials were revoked simultaneously). The attacker could have use a valid token to exfiltrate newly rotated secrets during the rotation window (which lasted a few days). This could have allowed the attacker to retain access and execute the March 19 attack.

Affected Components

Component Type Affected versions Fixed versions
aquasecurity/trivy Go / Container image 0.69.4 (latest tag also affected) 0.69.3
aquasecurity/trivy-action GitHub Actions All tags 0.0.1 – 0.34.2 (76/77) 0.35.0 (unaffected)
aquasecurity/setup-trivy GitHub Actions All 7 tags (v0.2.0 – v0.2.6) v0.2.6 (re-created with safe commit)

Exposure Window

Component Start (UTC) End (UTC) Duration
trivy v0.69.4 2026-03-19 18:22 1 2026-03-19 ~21:42 ~3 hours
trivy-action 2026-03-19 ~17:43 2 2026-03-20 ~05:40 ~12 hours
setup-trivy 2026-03-19 ~17:43 2 2026-03-19 ~21:44 ~4 hours

Attack Details

Trivy v0.69.4 binary and container images

The attacker created a malicious release by:

  1. Pushing a commit (1885610c) that swapped the actions/checkout reference to an imposter commit (70379aad) containing a composite action that downloaded malicious Go source files from a typosquatted domain
  2. Adding --skip=validate to goreleaser to bypass binary validation
  3. Tagging this commit as v0.69.4, triggering the release pipeline

The compromised release was distributed across different channels: GHCR, ECR Public, Docker Hub (both 0.69.4 and latest tags), deb/rpm packages, and get.trivy.dev.

trivy-action tag hijacking

The attacker force-pushed 76 of 77 version tags to malicious commits that injected an infostealer into entrypoint.sh. The malicious code executes before the legitimate Trivy scan and does the following:

  1. Dumps Runner.Worker process memory via /proc/<pid>/mem to extract secrets. Sweeps 50+ filesystem paths for SSH keys, AWS/GCP/Azure credentials, Kubernetes tokens, Docker configs, .env files, database credentials, and cryptocurrency wallets.
  2. Encrypts collected data using AES-256-CBC with RSA-4096 hybrid encryption.
  3. Transmits to attacker-controlled infrastructure. If exfiltration fails and INPUT_GITHUB_PAT is set, creates a public tpcp-docs repository on the victim's GitHub account and uploads stolen data as a release asset.

setup-trivy release replacement

All 7 existing tags (v0.2.0 – v0.2.6) were force-pushed to malicious commits. The malicious action.yaml contained the same infostealer as trivy-action, injected as a "Setup environment" step that executes before the legitimate Trivy installation.
We have removed all malicious releases within ~4 hours and re-created v0.2.6 with safe content. Tags v0.2.0 – v0.2.5 were not restored.

Who is NOT Affected

  • Users who pinned trivy to v0.69.3 or earlier
    • v0.69.3 is protected by GitHub's immutable releases feature (enabled March 3, before v0.69.3 was published)
    • v0.69.2 predates this setting but their integrity can be verified via sigstore signatures (see "How to Verify" section below)
  • Users who pulled container images by digest
  • Users who referenced [email protected]
    • 0.35.0 is protected by GitHub's immutable releases feature (enabled March 4, before 0.35.0 was published) and was not affected by the tag hijacking attack
  • Users who pinned trivy-action or setup-trivy to a safe commit SHA

Recommended Actions

Update to Known-Safe Versions

Component Safe Version
Trivy binary v0.69.2, v0.69.3
trivy-action v0.35.0
setup-trivy v0.2.6

Rotate All Potentially Exposed Secrets

Based on information shared above, if there is any possibility that a compromised version ran in your environment, all secrets accessible to affected pipelines must be treated as exposed and rotated immediately.

Audit Trivy Versions

Check whether your organization pulled or executed Trivy v0.69.4 from any source. Remove any affected artifacts immediately.

Audit GitHub Action References

Review all workflows using aquasecurity/trivy-action or aquasecurity/setup-trivy. If you referenced a version tag rather than a full commit SHA, check workflow run logs from March 19–20, 2026 for signs of compromise.

Search for Exfiltration Artifacts

Look for repositories named tpcp-docs in your GitHub organization. The presence of such a repository may indicate that the fallback exfiltration mechanism was triggered and secrets were successfully stolen.

Pin GitHub Actions to Full SHA Hashes

Pin GitHub Actions to full, immutable commit SHA hashes, don't use mutable version tags. As described here: https://docs.github.com/en/actions/reference/security/secure-use#using-third-party-actions

Regarding trivy-action: The original tags (0.0.10.34.2) were deleted during remediation. Because the attacker's force-push caused these tags to be treated as immutable releases by GitHub, they cannot be re-created with the same names. New tags have been published with a v prefix (v0.0.1v0.34.2) pointing to the original legitimate commits. Three tags: v0.0.10, v0.34.1, and v0.34.2 have not yet been restored. If you need to reference a version older than 0.35.0, use the v-prefixed tag (e.g., aquasecurity/[email protected] instead of @0.34.0).
We recommend pinning to a full commit SHA regardless of which tag you use.

How to Verify Existing Installations

Binary verification

# Download binary and sigstore bundle
curl -sLO "https://github.com/aquasecurity/trivy/releases/download/v0.69.2/trivy_0.69.2_Linux-64bit.tar.gz"
curl -sLO "https://github.com/aquasecurity/trivy/releases/download/v0.69.2/trivy_0.69.2_Linux-64bit.tar.gz.sigstore.json"

# Verify signature
$ cosign verify-blob \
  --certificate-identity-regexp 'https://github\.com/aquasecurity/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  --bundle trivy_0.69.2_Linux-64bit.tar.gz.sigstore.json \
  trivy_0.69.2_Linux-64bit.tar.gz
Verified OK

# Check signing timestamp
$ date -u -d @$(jq -r '.verificationMaterial.tlogEntries[].integratedTime' trivy_0.69.2_Linux-64bit.tar.gz.sigstore.json)
Sat Mar  1 19:11:02 UTC 2026
# ✅ Signed on Mar 1, before the attack on Mar 19

Container image verification

# Verify signature and get image digest
$ cosign verify \
  --certificate-identity-regexp 'https://github\.com/aquasecurity/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  --new-bundle-format \
  ghcr.io/aquasecurity/trivy:0.69.2
Verification for ghcr.io/aquasecurity/trivy:0.69.2 --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The code-signing certificate was verified using trusted certificate authority certificates

# Get digest and check all signing timestamps via Rekor
$ DIGEST=$(cosign verify \
  --certificate-identity-regexp 'https://github\.com/aquasecurity/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  --new-bundle-format -o json ghcr.io/aquasecurity/trivy:0.69.2 2>/dev/null | \
  jq -r '.[0].critical.image."docker-manifest-digest"')

$ rekor-cli search --sha "$DIGEST" | grep -v 'Found' | while read uuid; do
    rekor-cli get --uuid "$uuid" | grep IntegratedTime
  done
IntegratedTime: 2026-03-01T19:13:52Z
IntegratedTime: 2026-03-01T19:13:47Z
IntegratedTime: 2026-03-01T19:13:57Z
IntegratedTime: 2026-03-01T19:13:54Z
IntegratedTime: 2026-03-01T19:13:46Z
IntegratedTime: 2026-03-01T19:13:37Z
# ✅ All signed on Mar 1, before the attack on Mar 19

References

联系我们 contact @ memedata.com