Djangocon EU: supply chain attacks on Python projects - Mateusz Bełczowski¶
(One of my summaries of the 2026 Djangocon EU in Athens).
Full title: what’s in your dependencies? Supply chain attacks on Python projects.
How supply chain attacks work: attackers don’t attack your code directly, they target
something you trust. A typical Django project has lots of dependencies. Direct
dependencies and “transitive dependencies”, dependencies of our dependencies. If you
depend on requests, requests itself will grab certify and urllib3.
Possible package attacks:
Inject malicious code directly into the repo.
Create malicious package. Typosquatting (abusing typos), slopsquatting (abusing typos made by LLMs). “Brandjacking”: quickly after
deepseekbecame popular, adeepseekaipackage was published that stole credentials.Compromise existing package. Credential stealing, CI/CD exploits.
What attackers typically do with access is to steal credentials. Environment variables,
cloud keys (AWS_xyz), pypi tokens, ssh private keys, database URLs, saved passwords.
Example: num2words was hacked in July 2025. Phishing leading to maintainer credentials
theft. Fake login page at pypj.org instead of pypi.org. Then they uploaded faulty
releases with the captured credentials. Credentials weren’t rotated, so a second attack
happened a few days later. This malware targeted .pypirc files, leading to more
compromises.
How can we defend from this kind of attacks? Depends on the kind of attack. When publishing via GitHub actions, use “trusted publishing”, in that case there are no credentials to steal.
Another example: LiteLLM was compromised via trivy, a security scanner that itself was compromised… It in turn collected environment variables, secrets and ssh keys, bundled it all in a tarball and posted it to some legitimate-looking domain.
Some myths:
“Lockfiles protect us”. No, they only prevent accidental upgrades, not when adding a package for the first time.
“Just don’t install suspicious packages”. Lots is installed via transitive dependencies.
“We run everything in Docker so we’re safe”. It limits the blast radius, but credentials and environment variables are still at risk.
“We can fully prevent attacks”.
Some tips:
Use dependency cooldowns.
uvhas “exclude-newer”,piphas “uploaded-prior-to”. Don’t be the first to install a fresh release, as most malicious packages are discovered within hours or days.Pin versions and verify hashes.
Pypi is getting better:
Trusted publishing.
Project quarantine.
Attestations: cryptographic tools to verify the source.
Typosquatting protection.
AI has risks:
Slopsquatting. Hallucinated package names that get exploited.
Prompt injection via github issues.
Agents often “just” pip-install things directly.
Note: AI can also be used to detect malware! A small project started after the LiteLLM compromise managed to detect a dangerous different compromise almost the moment it was published. Nice!
Unrelated photo explanation: a cat I encountered in Athens on an evening stroll in the neighbourhood behind the hotel. It was a cat on the hunt: relevant to the topic of this talk :-)