Every week there's a new npm supply chain attack story. But here's the thing nobody talks about: PyPI has the exact same problem.
Last year, researchers found over 400 malicious packages on PyPI in a single month. Typosquatting, dependency confusion, and install-time code execution — all the same attack vectors as npm.
So I built a scanner for Python packages too.
Why PyPI Is Actually Worse
npm has npm audit. Python has... nothing built-in.
-
pip installrunssetup.pywith full system access — no sandbox - PyPI has no package signing by default
- No built-in security advisory database
-
requirements.txtdoesn't lock hashes by default
The Scanner
I wrote pypi-typosquat-scanner — same concept as my npm scanner, but for Python:
python scanner.py --package requests
python scanner.py --top 100
python scanner.py --file requirements.txt
It generates typo variations, checks if they exist on PyPI, and flags suspicious ones based on:
- Presence of network calls in setup.py
- Single maintainer + recent upload
- Missing description or homepage
- Name similarity score to popular packages
What I Found Scanning the Top 50
Out of ~2,800 typo variations of the top 50 PyPI packages:
- 189 existed as real packages
- 31 had suspicious setup.py files
- 12 made network requests during install
-
4 were uploaded in the last 30 days with names 1 character off from
requests,flask, ordjango
The scariest finding: a package called reqeusts (note the transposed letters) that had been downloaded 1,200 times before being removed.
How to Protect Your Python Projects
1. Always use hash-checking mode
pip install --require-hashes -r requirements.txt
2. Generate locked requirements with hashes
pip-compile --generate-hashes requirements.in
3. Audit your dependencies
pip-audit # From PyPA
safety check # From Safety
4. Review setup.py before installing unknown packages
pip download <package> --no-deps
tar -xzf *.tar.gz
cat */setup.py
The Ecosystem Needs to Change
Both npm and PyPI need:
- Mandatory 2FA for packages with >1000 downloads
- Fuzzy name matching during publish (reject "reqeusts" if "requests" exists)
- Sandboxed installs — setup.py should NOT have network access
- Signed packages by default
PEP 740 (index attestations) is a step in the right direction, but adoption is slow.
What's Your Setup?
How do you audit Python dependencies in your projects? Do you use pip-audit, safety, or something else?
I'm curious whether teams actually run --require-hashes in production — in my experience, almost nobody does.
Previously: I Scanned 500 npm Packages for Typosquatting. I write about supply chain security and developer tools.
Top comments (0)