Last week, the Python project “ultralytics” suffered a supply-chain attack through a compromise of the projects’ GitHub Actions workflows and subsequently its PyPI API token. No security flaw in PyPI was used to execute this attack. Versions 8.3.41, 8.3.42, 8.3.45, and 8.3.46 were affected and have been removed from PyPI.
The attack highlights the importance of securing software forges and the build and publish workflows for open source projects. A complete set of details is available
Despite the success of the attack, many things went right from PyPI’s perspective, especially the ability to audit the attack while it was occurring and after the fact. Because the Ultralytics project was using Trusted Publishing and the PyPA’s publishing GitHub Action: PyPI staff, volunteers, and security researchers were able to dig into how maliciously injected software was able to make its way into the package.
From looking at the Sigstore transparency logs and the PyPI provenance attestations, it was clear that the first set of injected packages were published through the existing GitHub Actions workflow, not by an API token. This considerably reduced the scope of the attack: either the malicious code was inside the source repository or was injected during the build phase. Later investigation showed that the attack targeted the GitHub Actions cache which was used during the build phase.
The second round of malicious releases came from the attacker using an unrevoked PyPI API token that was still available to the GitHub Actions workflow, potentially a hold-over from before the project adopted Trusted Publishing. This was detectable because there were no corresponding source repository activity or PyPI publish attestations for the second round of releases.
Once tools begin utilizing these publish attestations to record the “expected” provenance of software, this type of attack will be less effective as the lack of provenance information will be more apparent and verifiable at install time.
From this story, we can see a few places where PyPI can help developers towards a secure configuration without infringing on existing use-cases:
API tokens are allowed to go unused alongside Trusted Publishers. It’s valid for a project to use a mix of API tokens and Trusted Publishers because Trusted Publishers aren’t universally supported by all platforms. However, API tokens that are being unused over a period of time despite releases continuing to be published via Trusted Publishing is a strong indicator that the API token is no longer needed and can be revoked.
GitHub Environments are optional, but recommended, when using a GitHub Trusted Publisher. However, PyPI doesn’t fail or warn users that are using a GitHub Environment that the corresponding Trusted Publisher isn’t configured to require the GitHub Environment. This fact didn’t end up mattering for this specific attack, but during the investigation it was noticed as something easy for project maintainers to miss.
We’ve created tracking issues for both of the above changes.
Not every package and release on PyPI should be treated as trusted, it is up to you the user to review your usage of software from PyPI before choosing to install packages.
PyPI staff and volunteers do their best to remove malware, but because the service is open to anyone looking to publish software there is an unfortunately high amount of abuse. Thankfully most of this abuse does not have the same widespread impact as a targeted attack on an already widely-used project.
Mike Fiedler, the PyPI Safety and Security Engineer is working on new systems for reducing the time that malware is available to be installed on PyPI, through APIs that security researchers can automatically send reports to and new “quarantine” release status to prevent harm while a human investigates the situation. Expect more in this space in 2025!
If you are publishing software to PyPI then you can harden your build and publish workflow to avoid supply-chain attacks. Following a handful of security best-practices is enough to avoid becoming a target as the difficulty increases drastically for each added mitigation.
In addition to the specific recommendations above, we strongly recommend general account security best practices such as:
Prevention is important, but just as important is preparedness. Here’s what to do if your own project is compromised:
Massive thank-you to sponsors who make security work for Python and PyPI possible such as Alpha-Omega sponsoring Seth Larson as the Security Developer-in-Residence, Amazon Web Services sponsoring Mike Fiedler as the PyPI Safety and Security Engineer, and the Sovereign Tech Fund and the Google Open Source Security Team for sponsoring Trail of Bits to work on PyPI Attestations.
Digital signatures add another layer of security to your online transactions and communications. But how…
Unfortunately the string of phishing attacks using domain-confusionand legitimate-looking emails continues. This is the same…
SummaryI recently responded to an attack campaign where malicious actors injected code into GitHub Actions…
Internet security is leveling up with MPIC. While your organization likely won’t need to do…
Sept. 10: Get actionable insights from 20+ global experts as they discuss PQC readiness assessments,…
SummaryPyPI now checks for expired domains to prevent domain resurrection attacks,a type of supply-chain attack…
This website uses cookies.