Malicious PyPI Packages Typosquat Popular Python Libraries
On July 21, 2026, more than two dozen malicious PyPI and npm packages were flagged, typosquatting Python libraries and even a Debian system package.
Package registries absorbed another wave of malicious uploads this week. On July 21, 2026, our catalog recorded 25 new malicious packages across PyPI and npm, most flagged as critical severity. Several impersonate widely used Python libraries. One copies the name of a Debian system package, and another borrows the name of the XWorm remote access trojan. This is the same bulk-publishing pattern that has hit open-source registries repeatedly through 2026, and it keeps working for one reason: developers install by name and trust the registry to be clean.
None of these are big-name compromised projects. They are new, low-reputation packages designed to catch a typo, a copied install command, or an automated dependency resolver that grabs whatever name it is given. That makes them easy to dismiss individually and dangerous in aggregate.
What happened
Between July 20 and July 21, 2026, supplychainattack.org catalogued 25 malicious packages: 22 on PyPI and 3 on npm. The entries are marked critical or high severity, and PyPI removed most of the Python packages quickly after they were reported.
Two caveats up front. We do not have published download counts for the individual packages, and full payload analysis was not public for every entry at the time of writing. What we can confirm is the naming, and the names tell you a lot about who the operators were aiming at.
The PyPI batch splits into three groups. The first group typosquats real software:
- yfinanec, a one-letter change on
yfinance, the very popular Yahoo Finance market-data library. - xx-ent-wiki-sm, which matches the name of spaCy's multilingual NER model
xx_ent_wiki_sm. - zero123, which reuses the name of a known image-to-3D model.
- yelp-pkg, which borrows the
yelpname. - zlib1g-dev, which copies the name of a Debian and Ubuntu apt package, not a Python package at all.
The second group uses malware-adjacent or utility naming, most notably xwormclient, whose name references the XWorm RAT family, plus 7miners and aclient-sdk.
The third group is bulk throwaway names with no obvious target: yellorq, zmaker, zlsrc, zenomenallib, zabitog, zeubilamouche, zakuraweb, a1rn, adad, 3web, 3web-py, 3-0, and a placeholder-looking zzzzthisisitwantsafecheckitzzzz. Names like that are typical of automated publishing scripts and of test uploads that probe registry defenses.
On npm, three packages were flagged the same day: streak-calendar, streak-daycount, and the scoped package @apexfdn/apex.
The names that matter
A few of these deserve attention because the disguise is good enough to fool a tired engineer.
yfinanec is the clearest example. yfinance is installed constantly in trading bots, notebooks, and data pipelines. A single transposed or added character in a Dockerfile or a pip install line lands the fake instead of the real one, and nothing looks wrong until the code runs.
xx-ent-wiki-sm is more subtle. spaCy language models are usually installed with python -m spacy download, but many teams pin them in requirements.txt by the raw model name. A PyPI package with that exact name can slip into an ML build and be treated as the model.
zlib1g-dev is the one worth flagging to your whole team. That is a system library package you install with apt-get, not pip. Someone publishing it on PyPI is betting on confused copy-paste, broken install docs, or automation that pipes package names into the wrong installer. It is a small trick, but it targets exactly the kind of glue scripts nobody reviews closely.
xwormclient is the loudest name in the batch. XWorm is a commodity .NET remote access trojan sold on criminal forums, with capabilities that typically include remote control, keylogging, credential theft, and clipboard hijacking. We could not independently verify the exact payload shipped inside this specific PyPI package, so treat the name as a strong warning rather than a confirmed XWorm binary. Either way, the catalog rates it critical, and any install should be handled as a compromise.
How these PyPI and npm campaigns work
The mechanics behind bulk registry malware have been consistent all year, and recent coordinated campaigns document the playbook well. In early July 2026, Socket and BleepingComputer reported a cluster of roughly 17 packages published across npm and PyPI that impersonated SDKs for the payment services Paysafe, Skrill, and Neteller. According to that reporting, the packages were designed to exfiltrate credentials and continuous integration secrets to a command-and-control server, and they included sandbox-evasion and anti-analysis checks to avoid automated detection.
The delivery method is the part developers underestimate. On PyPI, pip install runs the package's build code (for example a setup.py) on your machine at install time, before you ever import anything. On npm, lifecycle scripts such as postinstall do the same job. That means a malicious package does not need you to run your app. Getting it into a build is enough.
From there the common goals are predictable: read environment variables and dotfiles, grab cloud and registry tokens, scan for crypto wallets, and ship the loot to a remote endpoint or a Discord or Telegram webhook. Palo Alto Networks Unit 42, which tracks npm supply chain activity, describes this steady stream of low-reputation malicious packages as an ongoing attack surface rather than a one-off event. The July 21 batch fits that description.
We are not attributing the specific July 21 packages to the payment-SDK operators. We are pointing out that the technique, install-time execution plus credential and secret theft, is the default pattern you should assume until per-package analysis says otherwise.
Who is affected
The realistic blast radius here is narrow but real. You are exposed if you installed any of the named packages, most likely through a typo, a bad copy-paste from documentation or an AI assistant, or an unpinned dependency resolver.
Data-science and machine-learning teams carry extra risk this round because of yfinanec, xx-ent-wiki-sm, and zero123. Finance and trading code that pulls market data is a natural target for the yfinance lookalike. CI pipelines are the worst case, because a build agent runs install code with access to tokens and secrets, and it does it without a human watching.
How to check if you are affected
Start by checking whether any of the flagged names are present in your Python environments.
pip list --format=freeze | grep -Ei 'yfinanec|yelp-pkg|xwormclient|zlib1g-dev|xx-ent-wiki-sm|zero123|aclient-sdk|7miners|yellorq|zmaker|zlsrc|zenomenallib|zabitog|zeubilamouche|zakuraweb|a1rn|adad|3web|3web-py'
Grep your dependency manifests and lockfiles too, since a name can be pinned even if it is not currently installed.
grep -REi 'yfinanec|yelp-pkg|xwormclient|zlib1g-dev|xx-ent-wiki-sm|zero123|aclient-sdk|7miners' \
requirements*.txt pyproject.toml poetry.lock Pipfile.lock setup.py setup.cfg
For the npm packages, check both installed trees and lockfiles.
npm ls streak-calendar streak-daycount @apexfdn/apex
grep -E 'streak-calendar|streak-daycount|@apexfdn/apex' package-lock.json yarn.lock pnpm-lock.yaml
If you use a private proxy or artifact cache (Artifactory, Nexus, GitHub Packages), search its logs for these names as well. Caches keep copies after the public registry removes the original.
Remediation
If you find a match, assume install-time code already ran on that machine and act accordingly.
First, remove the package and rebuild from a clean environment rather than editing in place.
pip uninstall -y yfinanec # substitute the package you found
Then rotate anything the affected host or CI job could reach: npm and PyPI publish tokens, cloud provider keys, CI/CD secrets and OIDC configs, SSH keys, and any credentials stored in environment variables or dotfiles on that machine. Rotate first and investigate second. Waiting to confirm exfiltration only gives an attacker more time.
Pin your dependencies with hashes so a resolver cannot silently pull a lookalike. In pip, that means pip install --require-hashes against a fully hashed requirements file. Verify the exact name and namespace of every important dependency against its official docs, especially spaCy models and anything you install by a bare model name.
To cut install-time execution risk, run installs with scripts disabled where you can. npm supports this directly:
npm ci --ignore-scripts
For Python, prefer building and installing from vetted wheels rather than source distributions, and run untrusted installs inside a sandbox or ephemeral container with no standing credentials.
FAQ
Is yfinance safe to use?
Yes. yfinance is the legitimate Yahoo Finance library and is not the package flagged here. The malicious upload is yfinanec, a one-letter lookalike. Double-check the spelling in your requirements files and confirm you installed yfinance exactly.
How do I know if I installed one of the July 21 malicious PyPI packages?
Run the pip list and grep commands above against your environments, manifests, and lockfiles. Also search any private registry cache, because those retain copies after PyPI removes a package. If a name matches, treat the host as compromised and rotate the tokens it could reach.
What is xwormclient and does it contain XWorm?
xwormclient is a PyPI package whose name references XWorm, a commodity remote access trojan. Our catalog rates it critical, but we did not independently confirm that it ships an actual XWorm binary, so treat the name as a warning rather than a verified payload. Regardless of the exact code, do not install it, and if you already did, handle it as a full compromise.
How do I stop pip and npm from running code during install?
For npm, use npm ci --ignore-scripts to skip lifecycle scripts like postinstall. For pip, install from prebuilt wheels instead of source distributions where possible, and run any untrusted install inside an ephemeral container that holds no long-lived credentials. Neither step is a complete fix, but both remove the easiest path a malicious package uses to run code before you import it.
Related catalog entries
- malicious-code-in-yfinanec-pypi-1tywoi
- malicious-code-in-xwormclient-pypi-g8xogl
- malicious-code-in-zlib1g-dev-pypi-z571s5
- malicious-code-in-xx-ent-wiki-sm-pypi-177sqq
- malicious-code-in-zero123-pypi-4p2n45
- malicious-code-in-yelp-pkg-pypi-7emxe8
- malicious-code-in-7miners-pypi-1g03k0
- malicious-code-in-aclient-sdk-pypi-1wcjrf
- malware-in-streak-calendar-1kbrrw
- malware-in-streak-daycount-1r5ilt
- malware-in-apexfdn-apex-19i7wh
- malicious-code-in-aet-test-pypi-1t6vqe
Sources
- npm and PyPI Malware Campaign Exfiltrates CI/CD Secrets Through Fake Payment SDKs · GBHackers
- Fake Paysafe, Skrill SDKs on npm and PyPI steal credentials · BleepingComputer
- Coordinated npm and PyPI Campaign Typosquats Popular Secure Payment Apps · Socket
- The npm Threat Landscape: Attack Surface and Mitigations (Updated July 15) · Palo Alto Networks Unit 42
- Xygeni Malicious Code Digest 79 · Xygeni