Ongoing
"Pwn requests": pull_request_target & workflow_run
The structural flaw behind most of the incidents on this page. pull_request deliberately withholds write permissions and secrets; pull_request_target was created to restore them, and becomes hazardous the moment maintainers treat it as a normal CI trigger. workflow_run carries the same risk and gets far less attention: the triggered workflow can access secrets and write tokens even when the workflow that triggered it could not. One industry scan found 38% of organizations have a workflow vulnerable to script injection or dangerous triggers. Since 8 December 2025, pull_request_target always runs the workflow file from the default branch and checks out the default branch, whatever branch the pull request targets. That closes attacks through an old, vulnerable workflow left on another branch. It does not help when the default branch workflow itself checks out and runs the pull request's code.
Click to open →December 2024
Ultralytics build cache poisoning
Template injection via a crafted branch name against a format.yml workflow using pull_request_target. Secrets including secrets._GITHUB_TOKEN were exfiltrated and the build cache poisoned to inject a cryptominer into v8.3.41 and v8.3.42. The read from researchers was that the attackers had write access but preferred extracting CI/CD secrets, then used them to poison the cache and ship malicious releases.
Click to open →August 2025
Nx "s1ngularity"
The injected script extracted a read/write GitHub token, a consequence of the workflow permissions setting, then created a branch replacing the CI script, triggered the publish workflow against that branch via the API using workflow_dispatch, and deleted branches and workflow runs to clean up. When publish ran, it had NPM_TOKEN in scope and exfiltrated it. The PR targeted an outdated branch that still carried the vulnerable workflow after it had been reverted on master. In phase two, the stolen GitHub tokens were used to flip thousands of private repositories to public. Downstream, one threat-intel group rode the consequences to full AWS administrator access at a victim org in under 72 hours, via OIDC trust chains and a CloudFormation IAM capability chain. No zero-days were involved.
Click to open →2023–2024
Self-hosted runner takeovers (PyTorch and others)
A fork PR makes you a "previous contributor," after which workflows run on the self-hosted runner without approval; default runner setup is non-ephemeral, so access persists. On PyTorch, researchers confirmed root on the runners and pulled GITHUB_TOKENs with extensive write access out of .git/config during active workflows. Against GitHub's own actions/runner-images, the access reached internal macOS private cloud vCenter and Azure credentials, and could have poisoned every hosted runner base image. TensorFlow's fix was requiring approval for all fork PRs and setting GITHUB_TOKEN to read-only on self-hosted runners.
Click to open →September 2025, returned 2026
GhostAction
327 compromised GitHub user accounts were used to inject workflows disguised as "Add GitHub Actions Security workflow" across 817 repositories, stealing 3,325 secrets. The actors enumerated secret names from legitimate workflow files first, then hardcoded those names into their own workflow, harvesting PyPI, npm, DockerHub, GitHub, Cloudflare, and AWS credentials. It came back in 2026. GitGuardian found the malicious workflow in 772 public repositories belonging to 373 users and organizations between 31 August and 30 September 2026, aimed at 2,577 secrets; GitHub held most of the runs for approval, and by 5 October only 16% of the repositories had removed the workflow. From 7 October Socket saw more than 500 accounts committing it to tens of thousands of repositories.
Click to open →July 2025
Toptal repo-visibility flip and wiper
73 repositories in the org went public within a five-minute window; at least 10 contained code to exfiltrate GitHub auth tokens and destroy victim systems. The payloads sat in preinstall/postinstall hooks, sending the token to a webhook endpoint then recursively deleting files on Windows and Linux. About 5,000 downloads occurred before removal. This was an org-owner compromise, and the very first action taken was flipping repo visibility.
Click to open →March – June 2025
Salesloft Drift GitHub → AWS pivot
Investigators found the threat actor UNC6395 in the Salesloft GitHub account from March through June 2025, downloading content from multiple repositories, adding a guest user, and establishing workflows. They then moved to Drift's AWS environment, took OAuth tokens for customer integrations, and used those to reach customer data. Downstream victims included Zscaler, Palo Alto Networks, Cloudflare, PagerDuty, and others. The interesting detail for the tier model: "add a guest user" and "establish workflows" are both persistence primitives that org admin grants.
Click to open →September 2025 / November 2025 / May 2026
Shai-Hulud self-propagating worm (1.0 & 2.0)
The worm made GitHub permissions the propagation mechanism. It validated available GitHub tokens and their permissions, then queried /user/repos?affiliation=owner,collaborator,organization_member to find repos where the compromised account had enough privilege. It planted shai-hulud-workflow.yml, exfiltrated ${{ toJSON(secrets) }} to a webhook, and made repos public, including any the victim merely held tokens for. The 2.0 variant registered the infected host as a self-hosted Actions runner named SHA1HULUD and planted an injection-prone workflow at .github/workflows/discussion.yaml, so opening a GitHub Discussion gave arbitrary command execution on the host. 2.0 compromised 796 npm packages, with credential exfiltration confirmed across more than 500 GitHub users spanning 150+ organizations. A smaller descendant, known as Mini Shai-Hulud, hit in May 2026: on 19 May one developer account takeover led to more than 630 malicious versions across 317 npm packages in about 20 minutes, including AntV packages. The TanStack compromise a week earlier came through a different door, Actions cache poisoning (see the cache poisoning incident).
Click to open →February 2026
hackerbot-claw autonomous agent RCE
An autonomous agent doing this at scale. It abused unsafe pull_request_target, unsanitized inputs, dynamic shell execution, and overprivileged GITHUB_TOKEN to get RCE on GitHub-hosted runners across at least six repositories, exfiltrating write-capable tokens in some cases. Targets included Trivy, avelino/awesome-go, microsoft/ai-discovery-agent, DataDog/datadog-iac-scanner, project-akri/akri, RustPython, and ambient-code/platform, where the vector was prompt injection via CLAUDE.md, which was blocked. On Trivy it stole a PAT through a pull_request_target workflow and used it to take over the repository.
Click to open →March – April 2026
TeamPCP tag force-overwrite campaign
The most complete demonstration of tag-write as a permission tier. On 19 March 2026 (CVE-2026-33634), continuing an attack that began in late February, the actors used credentials with tag-write privileges to publish Trivy v0.69.4 and force-overwrite 76 of 77 tags in aquasecurity/trivy-action and all seven in aquasecurity/setup-trivy, redirecting trusted versions to malicious commits with no visible change in release metadata. Checkmarx's KICS GitHub Action followed on 23 March, when all 35 of its tags were moved through a compromised service account, and on 24 March LiteLLM versions 1.82.7 and 1.82.8 were uploaded straight to PyPI with credentials taken from LiteLLM's own CI, where Trivy ran. Researchers traced at least seven waves through to @bitwarden/cli hijacked with stolen KICS npm tokens, and elementary-data via Actions script injection. Each compromised environment yielded the credentials for the next.
Click to open →Ongoing
Actions cache poisoning (Angular, TanStack)
Actions caches are shared between PR workflows and release workflows. One researcher's angular/dev-infra chain was script injection via ${{ github.head_ref }} in a pull_request_target workflow, then cache filling with a purpose-built tool. TanStack saw 84 malicious versions across 42 @tanstack/* packages from the same class of chain on 11 May 2026: a pull_request_target workflow ran a fork's code, which poisoned the pnpm store in the shared cache, and the release workflow restored it and leaked its npm OIDC token. There is no CVE for any of this; the cache is behaving exactly as designed.
Click to open →March – April 2026
prt-scan: automated pull_request_target attacks
The second AI-assisted campaign of 2026 against pull_request_target, after hackerbot-claw. Wiz traced more than 500 malicious pull requests in six waves from six accounts, starting on 11 March 2026. The largest burst came from one account that opened more than 475 pull requests in 26 hours from 2 April. Early waves used crude shell scripts; later ones used AI-generated payloads written for each repository's language, including a stage that tried to get past label-gated workflows. Fewer than one in ten attempts worked, but at least two npm packages were published with the stolen credentials. The attacker never needed access to a target repository, only a fork and a workflow that ran its code with secrets.
Click to open →May 2026
Megalodon: mass backdooring of CI workflows
On 18 May 2026, in about six hours, throwaway accounts pushed 5,718 commits into 5,561 public repositories, straight to the default branch and without pull requests. The commits claimed to come from bots such as build-bot and ci-bot, but no real account was linked to those names. A mass variant added a workflow that ran on push and pull_request_target and sent secrets out. A targeted variant replaced existing workflows with one that only runs on workflow_dispatch, a dormant backdoor the attacker can fire later through the API. At least one project, Tiledesk, then published npm versions built from the poisoned source; the npm account itself was never touched. How the attacker got push access to so many repositories is not established in the primary write-ups.
Click to open →August 2026
ChainDrop: a hijacked maintainer account publishes through trusted publishing
On 4 August 2026 an attacker used the GitHub account of the maintainer of keyv and cacheable, packages with well over 100 million weekly npm downloads together. The commits went straight to main, unsigned, which StepSecurity reads as a stolen token or session used through the API; how the account was taken is not known. The attacker then cut releases, and the projects' own release workflows published the malware through npm trusted publishing, with valid provenance. No npm token was stolen for this part. The payload, a descendant of Shai-Hulud 2.0, steals npm and GitHub tokens, cloud keys and SSH keys from developer machines and CI runners, publishes itself to every package the victim can publish, and in victims' repositories adds a workflow that dumps the secrets context, then deletes the branch. It also writes .vscode/tasks.json and .claude/settings.json into repositories to run again later. StepSecurity counted 2,212 versions of 444 packages within about four hours. Provenance showed which commit was built, not whether anyone should have pushed it.
Click to open →