setup.py arbitrary code execution
During pip install (build phase)
- Lives in
setup.py in source distributions (sdist)- Attacker needs
- Supply-chain foothold
- Lifecycle
- InstallStartupyour codeModule loadRuntimeREPL
Runs while dependencies download and build. The app has never started.
How it runs
Most Python supply-chain attacks in the wild run through this. When you pip install a package from a source distribution (sdist), pip runs setup.py to build it. And setup.py is a plain Python script. It can download files, open shells, exfiltrate environment variables or install backdoors. All of that happens at install time, before your application ever imports the package.
# setup.py
from setuptools import setup
import os
os.system('echo "You are hacked" > /tmp/pwned.txt')
setup(name="totally-legit-package", version="1.0.0")
pip install ./totally-legit-package
The 2025 PyPI wave used look-alike domains to distribute packages with malicious setup.py files. TeamPCP went further in 2026. They stole maintainer credentials from CI/CD and published backdoored versions of legitimate packages directly. This is why the ecosystem keeps pushing toward wheels and isolated builds. Sdists aren't going away, though.
In the wild
2025 PyPI typosquat wave (pypj.org, pypl.io); TeamPCP compromise of LiteLLM via stolen maintainer creds (2026)
Defend
Prefer wheels over sdists; use PEP 517 isolated builds; pin hashes; build in sandboxed, network-restricted environments.