Skip to content

Security Incident Report: aquasecurity/trivy-action Supply Chain Compromise (2026-03-19) #1

@CybotTM

Description

@CybotTM

Security Incident Report: aquasecurity/trivy-action Supply Chain Compromise

Date of incident: 2026-03-19
Date of detection: 2026-03-19 (StepSecurity Harden-Runner)
Date of remediation: 2026-03-20 – 2026-03-21
Status: Resolved
Reference: netresearch/ofelia#535


1. Executive Summary

On March 19, 2026, the GitHub Action aquasecurity/setup-trivy was compromised via a tag force-push attack. Malicious code was injected that exfiltrated GitHub Actions runner memory (containing secrets) to an attacker-controlled domain. One workflow run in our org was affected. The exposure was limited to a short-lived, read-only GITHUB_TOKEN. No secret rotation was required.

In response, we hardened all 68 repositories across the netresearch GitHub organization with SHA-pinned actions, Dependabot configuration, and org-level enforcement — completing a comprehensive supply chain security overhaul within 48 hours.


2. Incident Details

2.1 What Happened

Detail Value
Compromised action aquasecurity/setup-trivy@v0.2.1 (tag force-pushed with malicious code)
Attack vector Tag force-push — mutable tag references resolved to attacker-controlled code
Malicious behavior Bundled runner worker memory into tarball, POST'd to scan.aquasecurtiy.org (typosquatted)
Compromise window ~18:07 – 18:11 UTC, March 19, 2026
Detection StepSecurity Harden-Runner (audit mode) logged DNS resolution and outbound connection to 45.148.10.212:443
Reference https://www.stepsecurity.io/blog/trivy-compromised-a-second-time---malicious-v0-69-4-release

2.2 Our Exposure

1 workflow run was compromised across the entire org:

Repo Run Branch Time (UTC) Evidence
netresearch/ofelia #23309867575 main 2026-03-19 18:11 Malicious curl to scan.aquasecurtiy.org confirmed in logs

Root cause of exposure: The workflow used trivy-action@915b19b... (v0.28.0) which internally referenced setup-trivy@v0.2.1 by tag (not SHA). When the tag was force-pushed, the malicious code executed.

All other repos were protected because they used trivy-action@57a97c7... (v0.35.0) which SHA-pins setup-trivy internally.

2.3 Secrets Exposure Assessment

Secret In scope? Permissions Risk
GITHUB_TOKEN Yes contents: read, security-events: write Low — short-lived, read-only on public repo
secrets.GITLEAKS_KEY No Different job, different runner None
Docker/GHCR credentials No Different job None
Cosign/OIDC signing tokens No Different job None
Org-level secrets No Not referenced in trivy job None

Verdict: No secret rotation required. Verified no malicious SARIF uploads occurred.


3. Remediation Actions

3.1 Org-Level Enforcement

Setting Before After
sha_pinning_required false true

GitHub's org-level sha_pinning_required setting enforces that all GitHub Actions must be referenced by immutable commit SHA. Reusable workflows (@main, @tag) are explicitly exempt from this enforcement, allowing internal shared workflows to continue using branch references.

3.2 Repository Hardening

81 pull requests were created across the org:

Category Count
Merged 71
Closed (forks not maintained) 9
Auto-merge pending 1

Merged PRs (71)

Repository PR Additional fixes
composer-patches-plugin #69
concourse-ci-skill #13
context7-skill #16
data-tools-skill #6
dcind #6
docker-development-skill #12
docker-ftp-server #80, #81 Initial trivy pin + full hardening
docker-mariadb #26
docker-validator-w3c #108 Merge conflict resolved
enterprise-readiness-skill #31
file-search-skill #6
git-workflow-skill #20
github-project-skill #40
go-cron #348 Updated trivy-action v0.31→v0.35 (v0.31 had unpinned internal deps)
go-development-skill #23
ldap-manager #502 Fixed go.sum for templ v0.3.1001 transitive deps
maint #16
matrix-skill #16
molecule_http_docker_demo #27
moodle-docker #28, #29 Initial trivy pin + full hardening
netresearch-branding-skill #17
netresearch.github.io #13
node-magento-eqp #503 Branch updated
node-red-contrib-magento-eqp #373 Branch updated
nr-landingpage #2 PHPStan fixes, CGL fixes, functional test fix (missing setUpBackendUser)
ofelia #536
pagerangers-skill #20
php-modernization-skill #20
pipeline-factory #20
postdirekt-autocomplete-monorepo #132
raybeam #174
sdk-api-central-station #18 Pinned unpinned actions in workflow
sdk-eu-vat #18 Pinned unpinned actions, bumped phpunit for CVE-2026-24765
skill-repo-skill #35
t3x-cowriter #109
t3x-nr-image-optimize #44 PHPStan fixes, migrated to shared PHP-CS-Fixer config
t3x-nr-image-sitemap #29 Migrated to shared PHP-CS-Fixer config, added labeler.yml, fixed allow-plugins
t3x-nr-saml-auth #76 Added labeler.yml
t3x-nr-temporal-cache #57 TYPO3 v12/v13/v14 compat (IconSize), PHPStan fixes, missing translation key, functional test fixes
t3x-nr-textdb #88 Migrated to shared PHP-CS-Fixer config, added labeler.yml
t3x-nr-xliff-streaming #7 Added labeler.yml
t3x-scheduler #26 Removed strict_types from ext_emconf.php, Rector fix (ThrowWithPreviousExceptionRector), inlined CGL config for TYPO3 12 compat
t3x-sync #37 Removed strict_types from ext_emconf.php, migrated CGL config, inlined for TYPO3 12 compat
t3x-universal-messenger #37 Migrated to shared PHP-CS-Fixer config, added labeler.yml
terraform-provider-ad #11
timetracker #265
ttefsl #49
typo3-ci-workflows #28
typo3-ckeditor5-skill #15
typo3-conformance-skill #26
typo3-core-contributions-skill #13
typo3-ddev-skill #22
typo3-docs-ci-workflows #2
typo3-docs-skill #27
typo3-extension-upgrade-skill #15
typo3-project-upgrade-skill #2 Trimmed SKILL.md, fixed plugin.json, composer.json license
typo3-testing-skill #30
typo3-typoscript-ref-skill #3 Dual license migration, README markdown lint, ruff formatting
agent-rules-skill #20 Condensed SKILL.md to 447 words
ansible-role-gitlab-runner #10
ansible-role-monitoring-server #45 Replaced ansible-lint action with direct pip install
ansible_role_client_base #95 Pinned remaining unpinned actions, added .yamllint.yml
ansible_role_docker_containers #13, #14 Fixed molecule DinD with storage-driver: vfs
assetpicker #54
automated-assessment-skill #15
claude-coach-plugin #14 Created composer.json, fixed plugin.json, 48 ruff fixes
cli-tools-skill #17
composer-agent-skill-plugin #31
composer-audit-responsibility #9

Closed PRs (9 — forks not maintained)

Repository PR Reason
containers #1 Fork of bitnami/containers
docker-node-webserver #18 Fork of tobilg/docker-mini-webserver
guides #2 Fork of phpDocumentor/guides
matrix-docker-ansible-deploy #1 Fork of spantaleev/matrix-docker-ansible-deploy
news_importicsxml #1 Fork of georgringer/news_importicsxml
orocommerce #1 Fork of mollie/orocommerce
pforum #2 Fork of jweiland-net/pforum
typo3-mcp-server #4 Fork, upstream PRs only
codesnippet #5 Fork, not maintained

3.3 Additional Fixes (resolved during hardening)

Beyond SHA-pinning and Dependabot, the following pre-existing issues were discovered and fixed:

Issue Repos affected Fix
ext_emconf.php with declare(strict_types=1) t3x-scheduler, t3x-nr-image-sitemap, t3x-sync Removed — TER cannot parse it
Local PHP-CS-Fixer config not excluding ext_emconf.php t3x-nr-image-sitemap, t3x-sync, t3x-nr-textdb, t3x-scheduler, t3x-nr-image-optimize, t3x-universal-messenger Migrated to shared config from typo3-ci-workflows
Missing .github/labeler.yml 9 t3x-* repos Added standard labeler config
CVE-2026-24765 in phpunit sdk-eu-vat Bumped phpunit to ^10.5.62
TYPO3 v12/v13/v14 IconSize compat t3x-nr-temporal-cache Added class_exists fallback
Missing translation key causing functional test failures t3x-nr-temporal-cache Added button.view_content to locallang
Functional tests missing backend user setup nr-landingpage Added setUpBackendUser(1)
Rector: ThrowWithPreviousExceptionRector t3x-scheduler Passed $exception as previous
Docker-in-Docker overlay mount failure ansible_role_docker_containers Switched inner Docker to vfs storage driver
typo3-ci-workflows composer dep incompatible with TYPO3 12 t3x-scheduler, t3x-sync Inlined CGL config, pinned phpstan-typo3 ^1.0

4. Prevention Measures

4.1 Implemented

Measure Scope Impact
sha_pinning_required=true Org-wide All actions must use immutable SHA refs; reusable workflows exempt
SHA-pinned all third-party actions 68 repos Tags/branches can no longer resolve to compromised code
Dependabot for github-actions All repos Automatic PRs for action version updates with SHA pins
StepSecurity Harden-Runner 19 repos (audit mode) Detects malicious outbound connections

4.2 Recommended Future Improvements

Measure Priority Impact
Switch Harden-Runner from audit to block mode with domain allowlists High Would have prevented the data exfiltration
Expand Harden-Runner to remaining repos Medium Broader detection/prevention coverage
Upgrade to GitHub Team plan Medium Enables org-wide rulesets for branch protection

5. Tools & Methodology

Tool Purpose
pin-github-action (npm) Batch SHA-pinning with --allow "netresearch/*" to preserve internal workflow refs
gh CLI PR creation, merge, status checks, API operations
StepSecurity Harden-Runner insights Malicious connection detection and forensics
GitHub org-level sha_pinning_required API Org-wide enforcement of immutable action references

6. Timeline

Time (UTC) Event
2026-03-19 ~18:07 aquasecurity/setup-trivy tags force-pushed with malicious code
2026-03-19 18:11 ofelia CI run executes compromised code; Harden-Runner logs malicious connection
2026-03-19 ~18:15 Compromised tags removed by aquasecurity
2026-03-20 08:33 ofelia workflow updated to safe trivy-action v0.35.0
2026-03-20 10:07 StepSecurity files issue #535
2026-03-20 ~19:30 Investigation complete: 1 compromised run, low-risk exposure
2026-03-20 19:32 sha_pinning_required=true enabled org-wide
2026-03-20 19:45–21:00 Batch hardening: 59 PRs created across org
2026-03-20 21:00–23:30 CI fixes: pre-existing issues resolved across 20+ repos
2026-03-21 00:00 68/68 repos green, all PRs merged
2026-03-21 00:03 Issue #535 closed
2026-03-21 ~00:30 Team notified via Matrix #it channel

Report generated 2026-03-21. Contact: Sebastian Mendel

Metadata

Metadata

Assignees

No one assigned

    Labels

    securitySecurity incidents and advisories

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions