In December 2024, attackers published four malicious versions of ultralytics, the Python package behind the popular YOLO computer vision models, to PyPI. Versions 8.3.41 and 8.3.42 came out of the project's own GitHub Actions release workflow after an attacker exploited a known pattern: a workflow triggered by outside pull requests that placed the branch name straight into a shell command. Versions 8.3.45 and 8.3.46 were uploaded directly with a PyPI API token that, according to the Python Software Foundation, was still available to the workflow from before the project switched to Trusted Publishing. All four installed the XMRig cryptocurrency miner. The first version was flagged as malicious on 5 December, about ten hours after release. BleepingComputer reported more than 260,000 PyPI downloads in a single day at the time, and Google Colab users who ran the package had accounts flagged for "abusive activity." All four versions were removed by 7 December.
Key takeaways
- Four
ultralyticsreleases, 8.3.41, 8.3.42, 8.3.45 and 8.3.46, carried a cryptominer between 4 and 7 December 2024, according to the PyPI blog and William Woodruff's analysis. - The first two were built and published by Ultralytics' own GitHub Actions workflow after a malicious branch name triggered code execution in a workflow that ran on outsiders' pull requests. Woodruff believes the payload then poisoned the Actions cache used by the release build.
- The second two were uploaded with a long-lived PyPI API token that the PSF says was "potentially a hold-over" from before Trusted Publishing and had not been revoked.
- This was a confirmed compromise. Ultralytics founder Glenn Jocher confirmed that 8.3.41 and 8.3.42 "were compromised by a malicious code injection targeting cryptocurrency mining." No data theft has been reported.
- The identity lesson: moving to short-lived publishing does not help if the old long-lived token stays valid, and a CI workflow is only as trustworthy as the least trusted input it runs.
At a glance
| Organisations | Ultralytics (YOLO computer vision library on PyPI); downstream projects such as ComfyUI and SwarmUI and users including Google Colab notebooks |
|---|---|
| When | Malicious pull requests from 3 December 2024; first bad release 4 December 2024; flagged publicly 5 December 2024; last bad releases removed 7 December 2024 |
| Attacker | Unknown. Pull requests came from the GitHub account "openimbot" and others; Wiz notes the account had a long history and may itself have been compromised |
| Entry point | A GitHub Actions workflow triggered by outside pull requests that expanded the branch name into a shell command |
| Identities abused | The release workflow's publishing identity (Trusted Publishing) and workflow tokens; a leftover long-lived PyPI API token |
| Impact | XMRig cryptominer installed on machines that installed four releases; Colab accounts flagged; no data theft reported |
| Category | NHI, LLM / AI platform. Incident class: confirmed NHI breach (CI publishing identity and a leftover PyPI token abused to publish malware) |
What happened
Ultralytics maintains YOLO, a family of object detection models, and the ultralytics Python package that runs them. Wiz says the package is present in 10% of the cloud environments it sees, and it is a dependency of other AI tools, including the ComfyUI Impact Pack. The project publishes to PyPI from GitHub Actions using Trusted Publishing, which issues a short-lived credential to the workflow instead of using a stored token.
According to William Woodruff's analysis, one of Ultralytics' workflows ran on pull_request_target, a trigger that runs with the base repository's privileges even for pull requests from forks. A shared action it used ran git pull with the pull request's branch name inserted directly into a shell script. A near-identical injection had been reported by researcher Adnan Khan and fixed in August 2024, then reintroduced ten days later. On 4 December 2024, two pull requests arrived with crafted branch names. Wiz says the branch name piped a script into bash. Woodruff believes, and says the evidence "very strongly" suggests, that the payload poisoned the cache used by the release build. That evening, version 8.3.41 was built and published by the legitimate workflow. The PyPI blog confirms that Sigstore logs and provenance attestations showed it was not uploaded with an API token.
The malicious code downloaded and ran XMRig. A user flagged 8.3.41 on 5 December, and PyPI removed it that morning. Version 8.3.42 was published later that day and removed an hour after upload. BleepingComputer reported that Google Colab users who had installed the package were flagged for "abusive activity," and that ComfyUI and SwarmUI confirmed fresh installs would have pulled the miner. Jocher wrote on GitHub: "We have released 8.3.43 which addresses this security issue."
Then came a second wave. On 7 December, versions 8.3.45 and 8.3.46 were uploaded directly to PyPI with no matching activity in the repository and no attestations. The PSF's Seth Larson says these came from an unrevoked PyPI API token still available to the GitHub Actions workflow. The token's existence alongside Trusted Publishing is what allowed the attack to continue after the workflow was fixed. PyPI says it plans to address API tokens left active while Trusted Publishing is in use.
Timeline
| Date | Event |
|---|---|
| 14 August 2024 | Adnan Khan reports a near-identical template injection in Ultralytics' shared actions; it is fixed, then reintroduced on 24 August. |
| 3 December 2024 | A pull request containing a token-stealing script is submitted, according to Woodruff. |
| 4 December 2024 | Two pull requests with malicious branch names trigger the workflow; version 8.3.41 is published at about 20:50 UTC. |
| 5 December 2024 | 8.3.41 is reported as malicious at 06:34 UTC and removed at 09:15 UTC; 8.3.42 is published and removed an hour later; the attacking account is banned. |
| 7 December 2024 | 8.3.45 and 8.3.46 are uploaded with a leftover PyPI API token and removed the same morning. |
| 11 December 2024 | The PyPI blog publishes its analysis of the attack. |
How it happened: the identity attack path
- Untrusted input in a privileged workflow. A
pull_request_targetworkflow put an outsider's branch name into a shell command, giving the attacker code execution with the repository's CI privileges. - Poison the release build. From that foothold the attacker, Woodruff believes, wrote a poisoned entry into the shared Actions cache that the release job later restored.
- Publish with the project's own identity. The legitimate release workflow, holding the project's Trusted Publishing identity, built and uploaded 8.3.41 and 8.3.42 with the miner inside.
- Fall back to a static token. After the workflow was fixed, the attacker uploaded 8.3.45 and 8.3.46 with a long-lived PyPI API token that had never been revoked.
- Mine on every install. Each install, including transitive ones through AI tools and notebooks, ran XMRig on the user's machine.
Impact
- Confirmed: four malicious releases installed a cryptominer, according to Ultralytics, the PSF and Woodruff. Version 8.3.41 was available for about 12 hours.
- Reported: Google Colab users had accounts flagged for abusive activity, and downstream tools such as ComfyUI and SwarmUI pulled the miner on fresh installs, according to BleepingComputer.
- Not reported: theft of data or credentials from users' machines. BleepingComputer noted it was unclear at the time whether the malware did more than mine.
- Potential: an attacker with the same access could have shipped a credential stealer instead of a miner to every system that installs a widely used AI library.
What this means for NHI and AI agent security
The Ultralytics attack abused two non-human identities. The first was the release workflow itself: Trusted Publishing gave it a short-lived credential, which is good practice, but the workflow trusted a cache that an attacker-controlled job could write to. The second was a forgotten PyPI API token that outlived the move to Trusted Publishing. The PSF's advice afterwards was to rotate all long-lived secrets, and to treat any token still valid after a migration as live attack surface.
AI libraries are attractive targets because they are installed on GPU-rich machines, notebooks and cloud workloads, and pulled in as dependencies by other AI tools. A miner was the payload this time; the same access could have stolen cloud keys or model provider API keys. See our CI/CD Pipeline Identity Security Guide and AI Supply Chain and AI-BOM Guide.
Recommendations
- Revoke old tokens when you adopt trusted publishing. Delete every PyPI or npm API token once short-lived publishing works, and check none remain in CI secrets. See our Leaked Credential Response Playbook.
- Never run untrusted input in privileged workflows. Avoid
pull_request_targetwhere possible, and pass values such as branch names through environment variables rather than inline expressions. See our CI/CD Pipeline Identity Security Guide. - Separate release jobs from shared caches. Do not let release builds restore caches that less trusted jobs can write.
- Require a protected environment for publishing. Bind the trusted publisher to a GitHub environment with required reviewers, so a workflow compromise alone cannot publish.
- Check provenance on install. Releases without attestations or matching repository activity, as with 8.3.45 and 8.3.46, should be blocked or investigated. See our AI Supply Chain and AI-BOM Guide.
- Keep secrets off AI build and notebook environments. Use short-lived workload credentials on machines that install AI packages. See our AI Infrastructure Workload Identity Guide.
Frequently asked questions
Which Ultralytics versions were compromised?
Versions 8.3.41, 8.3.42, 8.3.45 and 8.3.46 on PyPI, published between 4 and 7 December 2024. All four have been removed. They installed the XMRig cryptocurrency miner.
How was the Ultralytics package compromised?
An attacker used crafted branch names in pull requests to run code in a GitHub Actions workflow that ran with repository privileges. The first two malicious versions were then published by the project's own release workflow. The last two were uploaded with a long-lived PyPI API token that had not been revoked after the project moved to Trusted Publishing.
Did the Ultralytics malware steal data?
No data theft has been reported. The payload installed a cryptocurrency miner. BleepingComputer noted it was unclear at first whether it did anything else, and advised anyone who installed an affected version to run a full system scan.
Related NHI Mgmt Group resources
Rspack npm compromise 2024 · ArtiPACKED 2024 · tj-actions/changed-files compromise 2025 · CI/CD Pipeline Identity Security Guide · AI Supply Chain and AI-BOM Guide
How NHI Mgmt Group can help
CI workflows, publishing identities and leftover API tokens are non-human identities that decide what millions of machines install. We help teams map them, retire static tokens and lock down release pipelines. See our NHI and AI agent security training.
References
- William Woodruff (ENOSUCHBLOG): zizmor would have caught the Ultralytics workflow vulnerability (6 December 2024)
- BleepingComputer: Ultralytics AI model hijacked to infect thousands with cryptominer (6 December 2024)
- Wiz: Ultralytics AI Library Hacked via GitHub for Cryptomining (9 December 2024)
- PyPI blog: Supply-chain attack analysis: Ultralytics (11 December 2024)