blog.pypi.org
Dustin Ingram, on behalf of the PyPI team.
A look back at the major changes to PyPI in 2025 and related statistics.
As 2025 comes to a close, it's time to look back at another busy year for the Python Package Index. This year, we've focused on delivering critical security enhancements, rolling out powerful new features for organizations, improving the overall user experience for the millions of developers who rely on PyPI every day, and responding to a number of security incidents with transparency.
But first, let's look at some numbers that illustrate the sheer scale of PyPI in 2025:
More than 3.9 million new files published
More than 130,000 new projects created
1.92 exabytes of total data transferred
2.56 trillion total requests served
81,000 requests per second on average
These numbers are a testament to the continued growth and vibrancy of the Python community.
Let's dive into some of the key improvements we've made to PyPI this year.
Security First, Security Always
Security is our top priority, and in 2025 we've shipped a number of features to make PyPI more secure than ever.
Enhanced Two-Factor Authentication (2FA) for Phishing Resistance
We've made significant improvements to our 2FA implementation, starting with email verification for TOTP-based logins. This adds an extra layer of security to your account by requiring you to confirm your login from a trusted device, when using a phishable 2FA method like TOTP.
Since rolling out these changes, we've seen:
more than 52% of active users with non-phishable 2FA enabled
more than 45,000 total unique verified logins
Trusted Publishing and Attestations
Trusted publishing continues to be a cornerstone of our security strategy. This year, we've expanded support to include GitLab Self-Managed instances, allowing maintainers to automate their release process without needing to manage long-lived API tokens. We've also introduced support for custom OIDC issuers for organizations, giving companies more control over their publishing pipelines.
Adoption of trusted publishing has been fantastic:
more than 50,000 projects are now using trusted publishing
more than 20% of all file uploads to PyPI in the last year were done via trusted publishers
We've also been hard at work on attestations, a security feature that allows publishers to make verifiable claims about their software. We've added support for attestations from all Trusted Publishing providers, and we're excited to see how the community uses this feature to improve the security of the software supply chain.
17% of all uploads to PyPI in the last year that included an attestation.
Proactive Security Measures
Beyond user-facing features, we've also implemented a number of proactive security measures to protect the registry from attack. These include:
Phishing Protection: To combat the ongoing threat of phishing attacks, PyPI now detects and warns users about untrusted domains.
Improved ZIP file security: We've hardened our upload pipeline to prevent a class of attacks involving malicious ZIP files.
Typosquatting detection: PyPI now automatically detects and flags potential typosquatting attempts during project creation.
Domain Resurrection Prevention: We now periodically check for expired domains to prevent domain resurrection attacks.
Spam Prevention: We've taken action against spam campaigns, including prohibiting registrations from specific domains that were a source of abuse.
Transparency and Incident Response
This year, we've also focused on providing transparent and timely information about security incidents affecting PyPI. We've published detailed incident reports on a number of events, including:
An issue with privileges persisting in organization teams.
A widespread phishing attack targeting PyPI users.
A token exfiltration campaign via GitHub Actions workflows.
The potential implications of the "Shai-Hulud" attack on the npm ecosystem.
We believe that transparency is key to building and maintaining trust with our community, and we'll continue to provide these reports as needed.
Safety and Support Requests
This year, our safety & support team and administrators have been working diligently to address user requests and combat malware to maintain a healthy ecosystem. We're proud to report significant progress in handling various types of support inquiries and improving our malware response.
Malware Response
We've continued to improve our malware detection and response capabilities. This year, we've processed more than 2000 malware reports. This is a testament to the vigilance of our community and the dedication of our administrators.
Our goal is to reduce the time it takes to remove malware from PyPI, and we're happy to report that we're making significant progress: in the last year, 66% of all reports were handled within 4 hours, climbing to 92% within 24 hours, with only a few more complex issues reaching the maximum of 4 days to remediate.
Support Requests
Our support team has also been hard at work making sure our users can continue to be effective on PyPI. This year, we've successfully resolved 2221 individual account recovery requests.
We've also handled more than 500 project name retention sequests (PEP 541). This includes an average first triage time less than 1 week. This is a significant improvement compared to the previous 9-month backlog, and we're happy to report that the backlog is current for the month of December.
Organizations Growth
One of our biggest announcements in previous years was the general availability of organizations on PyPI. Organizations provide a way for companies and community projects to manage their packages, teams, and billing in a centralized location.
We have continued to see growing usage of organizations:
7,742 of organizations have been created on PyPI
9,059 projects are now managed by organizations
We've been hard at work adding new features to organizations, including team management, project transfers, and a comprehensive admin interface. We're excited to see organizations use these features to use PyPI more effectively.
A Better PyPI for Everyone
Finally, we've made a number of improvements to the overall maintainer experience on PyPI. These include:
Project Lifecycle Management: You can now archive your projects to signal that they are no longer actively maintained. This is part of a larger effort to standardize project status markers as proposed in PEP 792.
New Terms of Service: We've introduced a new Terms of Service to formalize our policies and enable new features like organizations.
Looking Ahead to 2026
We're proud of the progress we've made in 2025, but we know there's always more to do. In 2026, we'll continue to focus on improving the security, stability, and usability of PyPI for the entire Python community.
Acknowledgements
As always, a huge thanks to our sponsors who make the scale and reliability of PyPI possible, and a special shout-out to Fastly for being a critical infrastructure donor.
We'd also like to extend a special thank you to a few individuals who made significant contributions to PyPI this year. Thank you to William Woodruff, Facundo Tuesca, and Seth Michael Larson for your work on trusted publishing, attestations, project archival, zipfile mitigation, and other security features.
Finally, PyPI wouldn't be what it is today without the countless hours of work from our community. A huge thank you to everyone who contributed code, opened an issue, or provided feedback this year. As always, we're grateful for the contributions of our community, whether it's through code, documentation, or feedback. PyPI wouldn't be what it is today without you.
Here's to a great 2026!
blog.pypi.org
Mike Fiedler
PyPI Admin, Safety & Security Engineer (PSF)
Shai-Hulud is a great worm, not yet a snake. Attack on npm ecosystem may have implications for PyPI.
PyPI and Shai-Hulud: Staying Secure Amid Emerging Threats
An attack on the npm ecosystem continues to evolve, exploiting compromised accounts to publish malicious packages. This campaign, dubbed Shai-Hulud, has targeted large volumes of packages in the JavaScript ecosystem, exfiltrating credentials to further propagate itself.
PyPI has not been exploited, however some PyPI credentials were found exposed in compromised repositories. We've revoked these tokens as a precaution, there's no evidence they have been used maliciously. This post raises awareness about the attack and encourages proactive steps to secure your accounts, especially if you're using build platforms to publish packages to PyPI.
How does this relate to PyPI?
This week, a security researcher disclosed long-lived PyPI credentials exposed as part of the Shai-Hulud campaign. The credentials were found in GitHub repositories (stored as repository secrets), and were still valid. We saw an attack with insecure workflow settings for Ultralytics in 2024.
While the campaign primarily targets npm, some projects use monorepo setups, publishing both JavaScript packages to npmjs.com and Python packages to PyPI from the same repository. When attackers compromise these repositories, they can extract credentials for multiple platforms.
We investigated the reported credentials and found they were associated with accounts that hadn't published recently. We've revoked these credentials and reached out to affected users to advise them to rotate any remaining tokens.
What can I do to protect my PyPI account?
Here are security practices to protect your PyPI account:
Use Trusted Publishing: If you are using a build platform to publish packages to PyPI, consider using a Trusted Publisher. This eliminates the need to manage long-lived authentication tokens, reducing the risk of credential exposure. Trusted Publishing uses short-lived, scoped tokens for each build, minimizing the impact of any potential compromise. This approach has risen in popularity, with other registries like Crates.io, RubyGems, and npmjs.com adopting similar models.
When using GitHub Actions, consider layering in additional security measures, like requiring human approval via GitHub Environments before publishing. This blog post from pyOpenSci has detailed guidance on adding manual review steps to GitHub Actions workflows.
Audit your workflows for misconfiguration: Review your GitHub Actions workflows for any potential security issues. Tools like zizmor and CodeQL can help identify vulnerabilities in your CI/CD pipelines. Adopt scanning as automated actions for the repository to catch future issues.
Review your account activity: Regularly check your PyPI account activity for any unauthorized actions. If you notice any suspicious activity, report it to the PyPI security team immediately.
Taking any of these steps helps mitigate the risk of compromise and keeps packages secure.
blog.pypi.org - The Python Package Index Blog - PyPI now checks for expired domains to prevent domain resurrection attacks, a type of supply-chain attack where someone buys an expired domain and uses it to take over PyPI accounts through password resets.
These changes improve PyPI's overall account security posture, making it harder for attackers to exploit expired domain names to gain unauthorized access to accounts.
Since early June 2025, PyPI has unverified over 1,800 email addresses when their associated domains entered expiration phases. This isn't a perfect solution, but it closes off a significant attack vector where the majority of interactions would appear completely legitimate.
Background
PyPI user accounts are linked to email addresses. Email addresses are tied to domain names; domain names can expire if unpaid, and someone else can purchase them.
During PyPI account registration, users are required to verify their email addresses by clicking a link sent to the email address provided during registration. This verification ensures the address is valid and accessible to the user, and may be used to send important account-related information, such as password reset requests, or for PyPI Admins to use to contact the user.
PyPI considers the account holder's initially verified email address a strong indicator of account ownership. Coupled with a form of Two-Factor Authentication (2FA), this helps to further secure the account.
Once expired, an attacker could register the expired domain, set up an email server, issue a password reset request, and gain access to accounts associated with that domain name.
Accounts with any activity after January 1 2024 will have 2FA enabled, and an attacker would need to have either the second factor, or perform a full account recovery.
For older accounts prior to the 2FA requirement date, having an email address domain expire could lead to account takeover, which is what we're attempting to prevent, as well as minimize potential exposure if an email domain does expire and change hands, regardless of whether the account has 2FA enabled.
This is not an imaginary attack - this has happened at least once for a PyPI project back in 2022, and other package ecosystems.
TL;DR: If a domain expires, don't consider email addresses associated with it verified any more.
blog.pypi.org - - The Python Package Index Blog - PyPI Users are receiving emails detailing them to log in to a fake PyPI site.
PyPI has not been hacked, but users are being targeted by a phishing attack that attempts to trick them into logging in to a fake PyPI site.
Over the past few days, users who have published projects on PyPI with their email in package metadata may have received an email titled:
[PyPI] Email verification
from the email address noreply@pypj.org.
Note the lowercase j in the domain name, which is not the official PyPI domain, pypi.org.
This is not a security breach of PyPI itself, but rather a phishing attempt that exploits the trust users have in PyPI.
The email instructs users to follow a link to verify their email address, which leads to a phishing site that looks like PyPI but is not the official site.
The user is prompted to log in, and the requests are passed back to PyPI, which may lead to the user believing they have logged in to PyPI, but in reality, they have provided their credentials to the phishing site.
PyPI Admins are looking into a few methods of handling this attack, and want to make sure users are aware of the phishing attempt while we investigate different options.
There is currently a banner on the PyPI homepage to warn users about this phishing attempt.
Always inspect the URL in the browser before logging in.
We are also waiting for CDN providers and name registrars to respond to the trademark and abuse notifications we have sent them regarding the phishing site.
If you have received this email, do not click on any links or provide any information. Instead, delete the email immediately.
If you have already clicked on the link and provided your credentials, we recommend changing your password on PyPI immediately. Inspect your account's Security History for anything unexpected.