How to Find GitHub Repos Vulnerable to Supply Chain Attacks Like CanisterWorm
On February 28th, a week-old GitHub account called hackerbot-claw opened a pull request (#10254, since deleted) on Trivy, a widely-used open-source security scanner, and immediately closed it. The GitHub Actions had already triggered. The attacker had secrets. StepSecurity's analysis confirmed the bot was systematically scanning public repos for exploitable pull_request_target workflows.
Aqua Security rotated credentials, but the rotation was incomplete. On March 19th, a separate group (TeamPCP) leveraged surviving credentials to force-push 76 version tags in trivy-action to point to malicious commits, publish a malicious Trivy binary (v0.69.4), and push compromised Docker Hub images. Every CI pipeline referencing those tags suddenly had its tokens exfiltrated. Those tokens fed into CanisterWorm: a self-propagating npm worm that compromised 135+ malicious package artifacts across 64+ unique packages before npm intervened.
The whole chain started with a misconfigured repository setting: fork PRs running GitHub Actions without approval.

What Setting Made This Possible?
GitHub gives each repo a set of controls for what happens when someone opens a pull request from a fork. For private repos, there's an explicit toggle: allow workflows to run from fork pull requests. For public repos, fork PR workflows are always enabled - the only gate is the approval policy, which controls whether a maintainer has to approve the run before it executes.
When the approval policy is set to none, any GitHub user can open a fork PR and run arbitrary code in your CI. If your workflows have access to secrets, those secrets leave with the attacker.
We've seen teams discover this the hard way. Not because they intentionally misconfigured anything, but because GitHub's defaults changed over time and nobody audited the setting across hundreds of repos. Clicking through every repo's settings page in the UI isn't realistic at scale. We've written about similar audit patterns before - like finding repos with unprotected default branches and PRs merged without review - and this follows the same playbook: turn a manual spot-check into a query you can run across your entire org.
Why We Built github_repository_fork_pr_workflow_settings
After the CanisterWorm incident, we wanted a way to answer one question across our entire org: which repos are vulnerable to this exact attack? The GitHub API exposes the data through two endpoints, but nobody wants to script that by hand for every repo. So we added a table to CloudQuery's GitHub Source that combines both into a single queryable surface:
That covers the full attack surface: can fork PRs run? Do they get secrets? Do they get write tokens? Does anyone have to approve them first?
How Do You Find Vulnerable Repos at Scale?
One query covers both public and private repos. Public repos are filtered by approval policy (fork PR workflows are always enabled, so that's the only gate). Private repos are filtered by whether someone explicitly turned on fork PR workflows:
Repos where send_secrets_and_variables is also true are the highest risk: fork PRs that run and receive your secrets.
How Should You Configure Fork PR Workflow Settings?
If you're maintaining open-source repos or private repos that accept fork contributions:
- Set the approval policy to
all_outside_collaboratorsat minimum. First-time contributors can't trigger workflows without a maintainer approving the run. For high-value repos, useallto require approval for every fork PR. - Audit
send_secrets_and_variablesandsend_write_tokens_to_workflows. If these are enabled alongside fork PR workflows, attackers who get code execution also get your credentials. - Review workflows using the
pull_request_targettrigger. Even with approval enabled, workflows that check out the fork's HEAD ref (${{ github.event.pull_request.head.ref }}) are running untrusted code in a trusted context. Repo settings alone won't catch this - it requires auditing the workflow files themselves.
If your CI pipelines rely on GitHub Actions from third-party repos, the keyless AWS access with OIDC pattern is worth considering too - it reduces the blast radius of a token exfiltration by scoping credentials to short-lived, narrowly-permissioned sessions.
How Do You Find pull_request_target Workflows with SQL?
The repo settings tell you if fork PRs can run. But even repos with approval enabled can be vulnerable if their workflow files use pull_request_target and check out the fork's code. That's what hackerbot-claw exploited on Trivy.
CloudQuery's Git Source plugin can sync workflow files from your repos so you can search them with SQL. We covered the plugin's full capabilities in the launch post - it supports syncing any file type with content, from Dockerfiles to CODEOWNERS. Configure it to sync .github/workflows/* with include_content: true, then join everything together to find repos with loose settings and pull_request_target workflows:
This isn't the only supply chain attack pattern you can detect with CloudQuery. The CodeBreach vulnerability post walks through a similar approach for AWS CodeBuild webhook exploits, and auditing CODEOWNERS against Okta catches orphaned code ownership after employees leave.
How Do You Scope the Blast Radius with CloudQuery Platform?
The queries above tell you which repos are vulnerable. But if you're responding to an active incident - or you want to report exposure to leadership - you need a way to track and communicate the scope. CloudQuery Platform lets you build reports on top of the synced data, so you can answer questions like: how many repos in our org have fork PRs running without approval? How many of those are also exposing secrets? Which teams own them?
Set up a Policy that flags repos matching the vulnerable criteria from the queries above, and you'll get continuous monitoring with alerts when new repos drift into a risky state. If you're dealing with incident response right now, the report gives you a single view to share with your security team instead of passing around spreadsheets or terminal output.
How to Set This Up
Add github_repository_fork_pr_workflow_settings to your synced tables in the CloudQuery GitHub Source. The table syncs to any CloudQuery Destination - PostgreSQL, ClickHouse, BigQuery, whichever your team already uses.
We built this table because the CanisterWorm attack exploited a setting that most teams didn't know existed, buried in a UI page that nobody audits at scale. Now you can query it across every repo in your org. If you want to talk through how to set this up or integrate it into your governance workflows, reach out to us.
Try CloudQuery yourself
Self-hosted, open source, and free to start. Or schedule a demo to see the managed version.




