← ~/logs LOG-005

>Supply Chain Security for Python

Real supply chain attacks on PyPI and a practical defense toolkit: pip-audit, hash pinning, Trusted Publishing, and continuous monitoring.

Mateusz Belczowski’s talk at DjangoCon Europe 2026 on supply chain attacks targeting Python packages and how to defend against them.

Every dependency runs with your privileges. pip install executes setup.py with full system access. No sandboxing. A typical Django project pulls in 50-100+ transitive dependencies.

Real incidents

Typosquatting. jeIlyfish (capital I, not L) impersonated jellyfish and stole SSH and GPG keys. It sat on PyPI for about a year. Over 500 fake Colorama variations deployed malware in 2024.

Phishing maintainers. In 2022, attackers sent emails impersonating PyPI with a fake “mandatory validation” link. Maintainers of deep-translator, exotel, and spam had their credentials stolen. Malicious versions were published under their accounts.

CI/CD pipeline attacks. Codecov’s Bash Uploader was modified via leaked Docker credentials in 2021, exfiltrating API keys from 23,000+ customers for two months. Ultralytics YOLO had a crypto miner injected via a GitHub Actions exploit in 2024.

Account hijacking. The ctx package was dormant for ~8 years. The attacker bought the expired domain of the maintainer’s email, used PyPI password reset, and published versions that stole AWS keys. ~27,000 malicious downloads.

The defense toolkit

Scan for known vulnerabilities:

pip install pip-audit
pip-audit                          # scan current environment
pip-audit -r requirements.txt      # scan a requirements file
pip-audit --fix                    # auto-update vulnerable packages

Pin with hashes, not just versions. A version pin doesn’t protect you if the file on PyPI gets replaced:

# With uv (recommended):
uv pip compile requirements.in --generate-hashes -o requirements.txt
uv pip install --require-hashes -r requirements.txt

uv also defaults to “first-index” resolution, which prevents dependency confusion attacks.

Evaluate before installing. Check deps.dev for dependency graphs and advisories, Scorecard for automated security scores, Socket.dev for supply chain red flags, and Libraries.io for release history.

Use Trusted Publishing. Replaces long-lived API tokens with short-lived OIDC tokens tied to CI providers. No token to steal. PEP 740 attestations provide Sigstore-based proof of where a package was built.

Monitor continuously. Run pip-audit in CI on every PR. Use Socket.dev’s GitHub app. Subscribe to advisories. Set up Dependabot or Renovate.

Key takeaways

  • Supply chain attacks are real and increasing on PyPI
  • Pin with hashes, not just versions
  • Scan continuously — run pip-audit in CI, not just once
  • Evaluate before you install — check deps.dev and Scorecard
  • Fewer dependencies = fewer attack vectors
  • AI tools can create new attack surface by suggesting packages that don’t exist

Slides | Experiment code