Last week, Trivy's repo was deleted out of nowhere.
An open-source security scanner used by thousands of teams globally, compromised in a way that should make us all sit up and pay very close attention.
Two questions from the incident kept bugging me:
- How did the attacker pull it off?
- How many other projects are susceptible to the same attack method?
Curiosity got the better of me and I started digging into how the attack worked. That curiosity sent me down a rabbit hole, which turned into a scanner, which turned up some results that genuinely took me by surprise.
Here's what I found.
What happened to Trivy
On February 27, 2026, Aqua Security's Trivy, an open-source vulnerability scanner, was compromised through its CI pipeline.
A GitHub account called hackerbot-claw (an AI-powered bot running Claude Opus 4.5) opened a pull request from a fork. Trivy's GitHub Actions workflow checked out the fork's code and ran it with Trivy's own credentials.
The impact was significant - CI tokens were stolen, releases deleted and a malicious VSCode extension was published with prompt injection payloads. The most interesting part of this attack was that the attacker was able to do this without any assigned permissions to the project.
Ultimately, this came down to a misconfigured GitHub Actions workflow.
This class of vulnerability has become known as a "Pwn Request" and though it is fairly well documented, it's an under-appreciated pattern that exists in other GitHub projects.
Trivy is a great product and it's a shame that they've been impacted by these events. As the incident unfolded, one key question had me down a rabbit hole for the past few days - how many other projects could be vulnerable to the same flaw?

How the vulnerability works
GitHub Actions has two triggers for pull requests:
on: pull_request runs the workflow in the fork's context - read-only permissions, no access to secrets. This is the safe default.
on: pull_request_target runs the workflow in the target repo's context - with its secrets, its write permissions, and its GITHUB_TOKEN. GitHub designed this for operations that need write access (labelling PRs, posting comments). But if the workflow then interacts with the fork's code or metadata, the attacker gains access to the target's credentials.
The attack vector
The workflow checks out the fork's code and executes it. The attacker's malicious code runs with the target repo's secrets and write access.
- Workflow triggers on
pull_request_target - Workflow runs
actions/checkoutwith the PR head ref (the fork's code) - Workflow executes that code - build steps, test scripts, whatever's in the repo
- All of this runs with the target repo's secrets and write access
This is the variant that compromised Trivy.

What we scanned
We built a scanner and pointed it at over 5,400 GitHub security-related repositories, prioritised by star count - the most-used projects first.
The pipeline:
- Discovery - identify target repos from security vendor orgs and relevant GitHub topics
- Scan - check every workflow file for
pull_request_target+ unsafe checkout refs - Validation - deep static analysis of all findings: resolve checkout refs, classify guard strength, map permissions, identify code execution paths
Of the repos we had initially scanned, we found:
- 488 had
pull_request_targetworkflows - the trigger that grants write access and secrets to PR-triggered builds - 90 potential matches where the workflow configuration could allow exploitation

Validating the results
Pattern matching over-flags. A workflow might reference head.sha in a concurrency group (harmless) rather than a checkout ref (dangerous). To separate real vulnerabilities from noise, every one of our 90 potential matches went through a second-pass validation framework.
For each flagged repo, the validator fetches the actual workflow YAML and runs five analysis passes:
- Checkout ref resolution - what code does the checkout step actually pull? Classifies each ref as attacker-controlled, safe, or unresolvable.
- Guard strength classification - does an
if:condition prevent exploitation? Classified as strong, moderate, weak, or none. The weakest guard across all jobs sets the rating. - Permissions mapping - what can the attacker do with the credentials? Maps effective
GITHUB_TOKENpermissions (write-all default vs. explicitly restricted). - Code execution path analysis - does attacker code actually run after the checkout? Also checks for unsafe interpolation of PR metadata in
run:blocks. - Explicit mitigation detection - has the maintainer documented awareness of the risk? Out of 90 flagged repos, exactly one (Anchore's Syft) had this.
These five passes feed into a verdict decision tree. Per workflow, worst case wins - from "Exploitable (trivial)" for unguarded workflows, through to "False positive" for safe checkout refs.

Validation results
Of our 90 potential matches, the validation framework confirmed 48 as exploitable. The remaining 42 broke down as follows:
- 28 false positives - safe patterns misidentified by the pattern matcher
- 5 mitigated - genuinely dangerous but adequately guarded
- 9 pending review - ambiguous enough to need manual trace
The scanner's initial flags were roughly 53% accurate. That false-positive rate is expected for a pattern-based first pass and validates the need for the second-pass framework.
During validation, we also found suspicious branches (poc-*, supply-chain) on two repos created during the hackerbot-claw campaign window which indicated that others may have been probing the same exploit pattern.
What we found
The validation confirmed 48 repositories as exploitable, with over 107,000 combined GitHub stars. 34 of those had no guards at all - any GitHub user can open a fork PR and get code execution with the target's credentials.
The scale of the findings is what stood out. This isn't isolated to one vendor or one type of project - the pattern spans cloud infrastructure, developer tooling, security platforms, and community projects:
- Major cloud providers (AWS, Azure, HashiCorp) - 12 repos across core infrastructure tooling
- Kubernetes and CNCF ecosystem projects
- Developer tools with tens of thousands of stars (google/langextract at 34K, go-task/task at 15K, bitnami/charts at 10K)
Perhaps the most telling finding: 7 of the exploitable repos are security tools themselves - projects specifically built to find vulnerabilities. This isn't about blaming maintainers. The distinction between safe and dangerous usage of pull_request_target is a 14-character difference in a checkout ref.

Proving it: controlled exploitation
Static analysis tells you if a lock is broken but we really wanted to pick it.
We built a controlled test bed in an isolated GitHub organisation to test our findings. For each exploitable finding, we created a fresh repository replicating only the vulnerable workflow configuration.
No source code, secrets or dependencies were harmed in this analysis.

The test cycle for each repo:
- Deploy - create a public repo with the replicated workflow YAML and a canary script that logs execution evidence
- Exploit - open a PR to trigger
pull_request_target - Capture - wait for GitHub Actions to run, pull workflow logs, record what executed and what permissions were available
- Destroy - delete the repo
Results
We weren't able to complete the full test cycle across all 48 repos due to platform rate limits, but from the 11 repos where we successfully captured results:
- 42 workflows pwned, 5 guards held - 89.4% exploitation rate
- Workflows based on repos from Google, AWS, CNCF and others were trivially exploitable with zero guards
- A workflow based on an AWS repo had 16 of 20 runs execute attacker code with 4 that had sufficient label-based guards to block execution.
- Only one developer tool with a label-based guard successfully held across all tests
What the logs showed
Every successful exploitation produced the same evidence pattern in the GitHub Actions run logs:
- Checkout confirmed - attacker-controlled code was checked out
- Canary executed - proof-of-concept script ran successfully
- Token present -
GITHUB_TOKENavailable with write permissions
The workflow checked out the PR branch (attacker-controlled code), executed it, and gave it a live GITHUB_TOKEN with write permissions. In a real attack, that's enough to push backdoored commits, delete releases, exfiltrate secrets, or - as hackerbot-claw demonstrated with Trivy - publish malicious packages.

Impact: what an attacker gets
Always present: GITHUB_TOKEN
Every workflow gets one. With default permissions (most of these repos), it grants write access to contents, PRs, issues, packages, and releases. An attacker can push commits to main, delete releases, or publish trojanised packages.
Usually present: repository secrets
API keys, deploy tokens, cloud credentials stored in GitHub's secrets manager. On pull_request_target workflows, these are accessible by default.
Increasingly present: OIDC tokens
If the repo uses GitHub's OIDC provider for cloud access (AWS, GCP, Azure), the attacker can request tokens from the runner and assume cloud IAM roles. No stored secret needed - the cloud trusts GitHub, GitHub trusts the workflow, and the workflow runs the attacker's code.

No insider access required. The Trivy attack was a random GitHub account opening a fork PR - no complexity, just a misconfigured YAML file.
How to fix it
Trivy fixed theirs within days. They replaced pull_request_target with the workflow_run pattern - a two-stage approach where stage 1 runs in the fork's context and stage 2 triggers separately with the target's credentials but only on trusted code.
The options for affected repos:
- Replace the trigger - use
workflow_runinstead ofpull_request_target - Fix the checkout - if you must use
pull_request_target, only check out the base branch, never the PR head - Add strong guards - restrict to same-repo PRs, dependabot only, or require maintainer labels
- Lock down permissions - set
permissions: {}to minimizeGITHUB_TOKENscope

Scope and disclosure
To be clear on what we did and didn't do - the scanning phase was entirely static analysis. We read publicly accessible workflow files via the GitHub API. We didn't open pull requests against any target, we didn't execute code in anyone's CI, and we didn't access any secrets.
When it came to proving the exploits, we built our own test environment, replicated the vulnerable configurations, and tore everything down after each test. We never touched a real target.
As mentioned earlier, this isn't about pointing fingers.
The pull_request_target trigger has legitimate uses and the difference between safe and dangerous is a 14-character change in a checkout ref which, in all honesty, is a very easy mistake for anyone to make.
Final thoughts
We should all look at the Trivy breach, and other similar incidents, as a wake-up call.
A well-maintained, widely-trusted security tool was compromised through a misconfiguration that many of us wouldn't spot in a code review.
It wasn't a sophisticated attack. It was a pull request and a workflow file that was doing what it was designed to do, just not with the safest controls in place to prevent abuse.
What this research showed us is that Trivy wasn't an outlier. The same pattern exists at scale across many repositories maintained by some of the biggest names in cloud, security and open-source.
The reality is there are probably more risks out there than any of us fully appreciate. CI/CD pipelines have become critical infrastructure but the way we secure them hasn't caught up. A 14-character difference in a YAML file shouldn't be the line between secure and compromised, but right now it is.
Code security has become a big focus for many organisations but if there's one takeaway from this research, it's that the security of your CI/CD pipeline deserves just as much attention as the code running through it.


