Djangocon EU: supply chain attacks on Python projects - Mateusz Bełczowski

Tags: django, djangocon

(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 deepseek became popular, a deepseekai package 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. uv has “exclude-newer”, pip has “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!

https://reinout.vanrees.org/images/2026/kat8.jpeg

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 :-)