certifi has 350M weekly downloads and one publisher. It handles your SSL certificates.
I ran the same supply chain analysis on Python that I did on npm. The findings are different — and in some ways worse.
I spent last week writing about npm supply chain risk. Then I ran the same analysis on Python.
The findings are different. In some ways worse.
The setup
I built a tool called Proof of Commitment that scores packages on behavioral signals: publisher depth, download momentum, release consistency, age. “Publisher depth” is the critical one — how many people have PyPI publish access? A package with one publisher and 300M weekly downloads is structurally fragile in a specific way: one compromised account enables a malicious publish to that entire install base.
For npm, the notable CRITICALs are things like chalk (413M/wk, 1 publisher), minimatch (581M/wk, 1 publisher), axios (99M/wk, 1 publisher). These are severe. But they’re visible — developers at least know they’re using chalk.
What I found in Python is different.
The top-line numbers
Running npx proof-of-commitment --pypi across the most-downloaded Python packages:
| Package | Downloads/wk | Publishers | Risk |
|---|---|---|---|
certifi | 350.7M | 1 | 🔴 CRITICAL |
charset-normalizer | 314.9M | 1 | 🔴 CRITICAL |
idna | 340.2M | 1 | 🔴 CRITICAL |
six | 240.0M | 1 | 🔴 CRITICAL |
cryptography | 264.8M | 1 | 🔴 CRITICAL |
attrs | 176.0M | 1 | 🔴 CRITICAL |
fastapi | 100.6M | 1 | 🔴 CRITICAL |
boto3 | 736.7M | 1 | 🔴 CRITICAL |
Eight CRITICAL packages in the top 25. Combined: roughly 2.5 billion downloads per week behind sole-publisher accounts.
Why certifi is the one to focus on
certifi provides Mozilla’s CA certificate bundle — the list of root certificates Python uses to verify that the server you’re talking to is who it claims to be. When your Python application makes an HTTPS request, certifi is what makes “this connection is secure” mean something.
It has 350.7 million weekly downloads. It has one PyPI publisher.
If that publisher’s account was compromised and a malicious version was pushed with rogue CA certificates included, an attacker could issue certificates that Python would trust as legitimate. This isn’t a theoretical escalation path. CA compromise is a well-documented attack class. The PyPI publisher gate is the last line of defense before your Python SSL stack.
pip audit shows zero vulnerabilities for certifi. There are no CVEs. The package is working exactly as intended. The risk is structural, not in the code.
The invisible dependency problem
Here’s the part that makes this particularly hard to reason about.
certifi is probably not in your requirements.txt. It’s a transitive dependency of requests, which is a dependency of essentially every Python project that makes HTTP calls. The chain looks like:
your-app
└── requests 3.0.x
├── certifi>=2017.4.17 ← 1 PyPI publisher, 350M downloads/wk
├── charset-normalizer>=2 ← 1 PyPI publisher, 314M downloads/wk
└── idna>=2.5 ← 1 PyPI publisher, 340M downloads/wk
You didn’t add these. You can’t see them in requirements.txt. They don’t show up in pip audit. But they’re running in production right now.
You can surface them:
# See what's actually in your environment
npx proof-of-commitment --pypi requests charset-normalizer certifi idna
# Or scan your lock file directly (finds transitive deps)
npx proof-of-commitment --file requirements.txt How this differs from npm
In npm, the most dangerous sole-publisher packages are often dependencies that used to have more maintainers and now don’t. minimatch (581M/wk) has been stable for years — one person holds the key.
In Python, the pattern is different. Several of the CRITICAL packages are intentionally single-author:
- charset-normalizer: Ahmed TAHRI (@Ousret) wrote it specifically to replace chardet. It’s his project. The risk isn’t abandonment — it’s that his PyPI account is the only gate.
- fastapi: Sebastián Ramírez (@tiangolo) is the author and sole publisher. FastAPI has 100M+ weekly downloads and 30K+ GitHub contributors — but one PyPI account.
- boto3: The AWS Python SDK goes through an
awsorganization account. Still technically 1 publisher in the PyPI sense.
The risk isn’t whether these maintainers are responsible. They are. The risk is the account itself: one phishing email, one credential leak, one compromised device.
This is exactly what happened to ua-parser-js in 2021 (npm) and to @bitwarden/cli in April 2026 (npm, via a different path). It will happen to a Python package. The structural conditions are already in place.
What good looks like
The packages that score well in Python:
| Package | Downloads/wk | Publishers | Risk |
|---|---|---|---|
requests | 336.5M | 3 | HEALTHY |
pip | 159.6M | 8 | HEALTHY |
typing-extensions | 326.7M | 6 | HEALTHY |
packaging | 417.5M | 4 | HEALTHY |
Multiple publishers means multiple compromised accounts would need to be breached simultaneously for a malicious publish. Not impossible, but significantly harder. This is the meaningful structural difference.
Check your own stack
# Audit any Python packages directly
npx proof-of-commitment --pypi requests flask django fastapi boto3
# Scan a requirements file
npx proof-of-commitment --file requirements.txt Web view (no install): getcommit.dev/audit
The npm ecosystem gets most of the supply chain attention. Python’s numbers are comparable. The difference is that Python’s CRITICAL packages are more likely to be hidden transitive dependencies — packages you didn’t explicitly install and can’t easily see without tooling. That invisibility is itself the problem.
Proof of Commitment is open-source. Web audit at getcommit.dev/audit. Data accurate as of May 4, 2026.
Also: Why npm audit returns zero for the most dangerous packages