The Malicious torchtriton Package That Hit PyTorch Users
On this page
The code was fine. The install wasn't — pip pulled an attacker's package with the right name off the public index.
| When | December 2022 |
|---|---|
| Target | PyTorch-nightly (Linux) users |
| Vendor | PyTorch / Meta; PyPI |
| Technique | Dependency confusion / name-squatting on PyPI |
| Impact | SSH keys, env vars, and system files exfiltrated via DNS |
- 1An attacker uploads a malicious torchtriton to public PyPI
- 2pip prefers PyPI over PyTorch's own nightly index for that name (dependency confusion)
- 3PyTorch-nightly installs pull the trojan, which exfiltrates keys and files
What happened
Over the 2022 holidays, an attacker uploaded a malicious package named torchtriton to PyPI — the same name as a dependency PyTorch ships on its own nightly index. Because pip gives public PyPI precedence, anyone installing PyTorch-nightly on Linux via pip between Dec 25–30 pulled the malicious version, whose binary read SSH keys, git config, environment variables, and home-directory files and exfiltrated them via DNS to an attacker domain.
How the attack worked
Dependency confusion: when a private-index package name also exists on public PyPI, the installer may prefer the public one. The attacker registered the name of PyTorch's nightly-index dependency on PyPI and let pip do the rest.
Root cause
A build/install pipeline that trusted package names without pinning their source, so a public namespace collision became remote code execution on developers' machines.
What a control would have caught
Namespace reservation and index-source pinning (or hash-pinned lockfiles) prevent the public index from ever satisfying a private dependency — the exact gap here.
How to prevent it
- Pin the index and hashes for internal dependencies; reserve their names publicly.
- Treat install-time code as code — scan and sandbox it.
- Monitor for typo/name-squats of your packages.
Feel it yourselfThe replay lab plants a tampered dependency that runs attacker code at install — the supply-chain class.
FAQ
What is dependency confusion?
When a package name used on a private index also exists on public PyPI, the installer may pull the public one. Here the attacker registered the name of a dependency PyTorch served from its own nightly index (torchtriton) on PyPI, and pip preferred it.
What did the malware do?
It read /etc/passwd, /etc/hosts, ~/.gitconfig, ~/.ssh/*, environment variables, and the first 1,000 files in the home directory, then exfiltrated them via DNS to an attacker domain.
How was it fixed?
PyTorch renamed the package to pytorch-triton, registered a dummy placeholder on PyPI to block re-squatting, and removed the malicious version with the PyPI security team.