Ultralytics PyPI releases shipped cryptominer
Attackers abused Ultralytics GitHub Actions to publish four PyPI releases with cryptominer code. The trigger combined pull_request_target with branch-name injection.
Story
The Ultralytics attack began in CI, not in PyPI. The project used a pull_request_target workflow and passed a privileged token into a custom action. That action then evaluated a user-controlled branch name inside a shell command.
The attacker named the branch as a command substitution. When the workflow ran, the branch name fetched and executed a remote shell script from GitHub, turning formatting automation into code execution on a privileged runner.
The attacker used that path to publish compromised PyPI releases. Versions 8.3.41, 8.3.42, 8.3.45, and 8.3.46 carried cryptomining changes, while the public repository did not contain matching malicious source. The package still looked like a normal computer-vision library release to downstream users.
The project cleaned up the releases and GitHub published GHSA-32hc-9xrg-cc9g. The durable lesson is simple: pull_request_target can be safe only when untrusted fork input is kept out of privileged execution.
Affected Artifacts
- Observed
- 2024-12-04 to 2024-12-07
- Fixed
- Not listed
- Hashes
-
- sha256:23d1f5dcec5d678a34a5947d615f3c3d31246e935bb8c93d9f7c790a23b19a8c
- sha256:16b1a872b13c63c9a5d75cfb5cdec76a6a4fd95a7d42f5fc3ca3d40b78b80fe7
- sha256:e2e05bdc1b2f22fef4a14d4fe4b4f21b8d15f83ceb4a9a4a21f5f6e02cb25a1c
- +1 more
Incident Context
- Motive
- Financial Gain
- Attribution
- Person
- Cause
- Gha Vulnerability
- Transitive
- No
- Actor
- Individual Hacker
External References
- The Ultralytics Supply Chain Attack: How It Happened, How to Preventlegitsecurity.com
- Ultralytics AI Supply Chain Attacksafetycli.com
- PyPI package compromisedgithub.com
- Ultralytics PyPI package compromisegithub.com
Source record: oss/attacks/ultralytics/meta.yaml