In April 2024, security researchers at Phylum flagged a batch of new PyPI uploads with names like "reqargs" and "reqpost" — near-perfect echoes of the ubiquitous requests library — quietly siphoning environment variables to a remote server the moment they were installed. It was not an isolated incident. PyPI typosquatting has become one of the most reliable ways for attackers to slip a malicious Python package into a developer's environment, because it exploits something no firewall can patch: a single mistyped pip install command. Since the technique was first documented on PyPI in 2017, researchers have catalogued thousands of typosquatted uploads, ranging from crude copy-paste clones to multi-stage droppers that install cleanly, pass a casual glance at the source, and only detonate once imported into a running process. For any team that treats pip install as routine, understanding how these attacks work — and why PyPI is such fertile ground for them — is no longer optional.
What Is PyPI Typosquatting?
PyPI typosquatting is the practice of publishing a package to the Python Package Index under a name that is a deliberate misspelling, hyphen swap, pluralization, or homoglyph of a popular library, betting that a developer's typo — or a stale tutorial, or a hurried copy-paste — will install the impostor instead of the real thing. The pattern is old but persistent: in 2017, "colourama" appeared on PyPI as a near-clone of the popular "colorama" terminal-coloring library, bundling hidden code that hijacked the Windows clipboard to swap in an attacker's cryptocurrency wallet address whenever a victim copied one. Since then the naming tricks have gotten subtler. Researchers at Checkmarx documented "jeIlyfish" — spelled with a capital "I" in place of a lowercase "l" — sitting on PyPI as a lookalike for the legitimate "jellyfish" fuzzy-matching library. Others have registered "beautifulsoup" without the trailing "4," "python3-dateutil" as a decoy for "python-dateutil," and dozens of variants on "urllib" trading on the popularity of "urllib3." None of these require any technical sophistication to register — only a few minutes and a PyPI account.
How Do Attackers Build a Malicious Python Package That Looks Legitimate?
Attackers build convincing malicious Python packages by cloning everything a developer would check before trusting a library — the README, the changelog, even the version history — while hiding the payload in the one place most people never read: the install script. Because setup.py and, more recently, pyproject.toml build hooks execute arbitrary code the instant pip install runs, a package never even needs to be imported to compromise a machine; the damage is done before a single line of the developer's own code executes. The W4SP Stealer campaign, tracked by Checkmarx and Phylum through 2022 and 2023, showed the model at scale: hundreds of typosquatted packages impersonating libraries like "python-dotenv" and "pyfiglet" shipped mostly legitimate-looking code with a heavily obfuscated payload appended at the end, which harvested browser-saved passwords, Discord tokens, and crypto wallet files and exfiltrated them via webhook. Some campaigns go further, delaying the malicious behavior for days or checking for the presence of a debugger or CI environment before firing, specifically to defeat quick sandbox scans.
What Real-World PyPI Supply Chain Attacks Have Targeted Developers?
Real PyPI supply chain attacks have already cost developers credentials, cloud access, and — in at least one case — years of undetected compromise. "Fabrice," a typosquat of the widely used "Fabric" SSH automation library, sat on PyPI from 2018 until ReversingLabs discovered and reported it in 2021; by the time it was pulled it had racked up roughly 37,000 downloads while quietly stealing AWS credentials and environment variables from every machine that installed it. In December 2022, the PyTorch team disclosed a more targeted pypi supply chain attack: a malicious package called "torchtriton" was uploaded to the public PyPI index under the same name as an internal PyTorch dependency. Because pip, by default, resolves the highest-priority match across configured indexes, the public malicious package won out over the private internal one — a class of attack known as dependency confusion — and exfiltrated SSH keys, hostnames, and environment data from machines running PyTorch's nightly build process. More recently, threat-intel teams at Socket and Phylum have reported pulling thousands of malicious or typosquatted packages from PyPI and npm combined every year since 2023, a steady cadence that shows no sign of slowing.
Why Is Python Package Registry Security So Hard for PyPI?
Python package registry security is difficult because PyPI was designed for open, frictionless publishing rather than pre-upload verification — anyone can create an account and push a new package live within minutes, with no human review gate in between. That openness is core to why the Python ecosystem grew so fast, but it also means the registry now hosts more than 600,000 projects, with tens of thousands of new releases published every month, making manual curation impossible at scale. PyPI's own security team has responded with real improvements: mandatory two-factor authentication for maintainers of "critical" projects since 2023, a "Trusted Publishers" mechanism that lets projects publish via short-lived OIDC tokens instead of long-lived API keys, and a package quarantine feature introduced in 2024 that flags suspected malware before a report is fully investigated. Even so, the fundamental asymmetry remains: it takes an attacker minutes to upload a convincing typosquat, and it takes a researcher or automated scanner far longer to notice, analyze, and get it taken down — a window during which every pip install is a bet.
What Can Developers Do to Protect Themselves Right Now?
Developers can meaningfully cut their exposure today by treating every new dependency the way they'd treat a new vendor, not a search result. That starts with the basics: pin exact versions and use lockfiles with hash verification (pip install --require-hashes) so a build can't silently pull in a newer, compromised release or a swapped-in typosquat. Before adding any new package, check its maintainer history, release cadence, and download counts on PyPI rather than trusting a blog post or an AI-generated code snippet that may itself hallucinate a plausible-sounding but nonexistent — and squattable — package name. Teams should also run CI installs in sandboxed, network-restricted environments so that even if a malicious python package slips through, its install-time exfiltration attempt has nowhere to send data, and route internal package names through Trusted Publishers or a private index with strict namespace reservation to close off dependency-confusion paths like the one used against PyTorch. None of this replaces automated scanning, but it removes the easiest wins for an attacker relying on a moment of inattention.
How Safeguard Helps
Safeguard is built for exactly this asymmetry: attackers only need one successful install, so defense has to be continuous, not occasional. Safeguard continuously monitors your organization's actual dependency manifests — across Python, JavaScript, and other ecosystems — against a live feed of newly published PyPI packages, flagging names that are one character, one hyphen, or one homoglyph away from something your team already depends on, before a typo ever reaches a developer's laptop or a CI pipeline. Rather than relying solely on after-the-fact malware databases, Safeguard correlates package metadata, publish velocity, maintainer reputation, and install-time behavior to catch both classic PyPI typosquatting and dependency-confusion patterns like the torchtriton incident, then blocks or quarantines the install before it can execute in your build environment. For security and platform teams accountable for python package registry security across dozens of repositories, Safeguard also generates SBOM-backed provenance records for every dependency pulled into production, so when the next malicious python package surfaces — and given the pace of the last three years, it will — you can answer "are we exposed?" in minutes instead of days of manual dependency archaeology.