Check requirements.txt for malicious PyPI packages
requirements.txt is the most common way Python projects declare dependencies, and how precise an answer we can give depends entirely on whether you pinned versions. Exact pins give a confirmed answer; unpinned entries give an advisory.
We check it against 374 compromised PyPI packages drawn from 35 tracked incidents. Everything runs in your browser - your requirements.txt never leaves your machine.
Parsed locally in your browser. Nothing leaves your device, no logging, no network round-trip.
What we read from your requirements.txt
- exact pins -
mistralai==2.4.6 - ranges and compatible-release specifiers -
urllib3>=1.26,<2.0,numpy~=1.26.0 - extras and environment markers -
requests[security]==2.31.0,black; sys_platform == "darwin" - bare entries with no version, reported as advisories rather than findings
Confirmed matches
Entries pinned with `==` give a confirmed answer. Entries with a range, or with no version at all, are reported separately as advisories - we can tell you the package has had compromised releases, but not whether you installed one.
Things worth knowing about requirements.txt
Unpinned dependencies cannot be confirmed
A bare aioquic line tells pip to install whatever is newest at the time. We cannot know which version landed on your machine, so we surface it as an advisory: this package has had malicious releases, go and check what you actually have installed with pip show.
Install-time execution is the norm on PyPI
A large share of the PyPI incidents we track execute during installation via setup.py or a build hook, rather than waiting to be imported. pip install is enough to detonate them, which means a failed or cancelled install still counts as exposure.
Name collisions across ecosystems are real
Some names exist on both npm and PyPI - mistralai is a live example in our own database. We match strictly within the PyPI ecosystem for this file, so a compromised npm package of the same name will not produce a false positive here.
Recent PyPI compromises we check for
The most recent of 35 tracked incidents affecting this ecosystem.
- GitHub Advisory malware sweep - 2026-08-17 / 2026-08-18 batch (Sui blockchain `@mysten/*` typosquat days 4-5 continuation `sui-move-graphql`+`sui-move-rpc`+`sui-gql-core`+`bcs-core`+`bucket-protocol-sdk-v2`, Tinkoff BNPL dep-confusion tail `bnpl-blocks-independent-bnpl-search`, LEB128 encoding typosquat pair `leb128x`+`ulebkit`, generic CWE-506 boilerplate `blastradar`+`runtime-health`, PyPI `socks5901` Android `/sdcard/` Telegram-bot exfiltrator)
- GitHub Advisory quiet-tail sweep - 2026-08-16 / 2026-08-17 (`@ai-vertical/ai-agent` npm generic-malware + `kb-ai` PyPI OpenSSF `setup.py`-install pentest dep-confusion demo)
- GitHub Advisory PyPI CWE-506 sweep - 2026-08-11 batch (`joule-sbx-poc`+`joule-btp-extension` 2026-08-joule-btp-extension localhost-exfil + reverse-shell PROBABLY_PENTEST pair, `telebot-pro` 2026-08-telebot-pro Telegram-session hidden-thread infostealer, `euler-sdk`+`morpho-sdk` GENERIC-standard-pypi-install-pentest setup.py install-hook IP+username exfil, `dlmm-sdk`+`dlmm` 2026-08-dlmm MALICIOUS env-var + credential + crypto wallet-directory enumeration)
- GitHub Advisory PyPI CWE-506 sweep - 2026-08-09..2026-08-11 batch (`neutrl-core`+`neutrl-contracts`+`plp-contract` credential-stealing dep-hidden campaign 2026-08-neutrl-core, `kotanku`+`kotoraka`+`btcflx`+`btcflip` Telegram-bot wallet-file exfiltrator quartet 2026-08-kotanku campaign, `pytablute` 2025-11-spellcheckers multi-stage RCE + polling C2, `chaintest` DPRK Contagious-Interview-adjacent browser+wallet+clipboard+SSH-key infostealer, `bigtime` open()-hook file-write exfiltrator 2026-08-bigtime campaign, `cubesat-upstream-driver` env-var reconnaissance dep-confusion PROBABLY_PENTEST)
- GitHub Advisory PyPI CWE-506 sweep - 2026-08-08 batch (`riakcs` Basho Riak-CS Python client typosquat with setup.py install-time host reconnaissance)
- GitHub Advisory PyPI CWE-506 sweep - 10-package 2026-08-07 batch (`2026-08-alphalend-layouts` Sui keystore-stealer pair with PTH persistence + `2026-08-flasq` typosquat wave: `pydanticc`+`flasq`+`idnna`+`fastapii`+`fast-hashes`+`speed-hashes` crypto-wallet stealers + `cdktn-provider-azurerm` cdktf HashiCorp jsii-chain typosquat + `atlas-internal` dep-confusion recon)
- GitHub Advisory PyPI CWE-506 sweep - 3-package 2026-08-06 batch (`xAyOuB-XcTxTeaM` Garena Free Fire spam-cannon botnet + `uncrypt` browser infostealer + `decapod-common` pentest)
- GitHub Advisory PyPI CWE-506 sweep - 4-package 2026-08-05 batch (`2026-08-bip39-py` crypto-wallet infostealer campaign: `solana-sniper-bot` + `eth-account-wallet` + `mnemonic-py` + `defi-sdk-py`)
requirements.txt security questions
- What if my requirements.txt has no pinned versions?
- We still check it, but the result is an advisory rather than a confirmed finding - we can tell you a package has had malicious releases without knowing which version you installed. Run
pip freeze > requirements-lock.txtand paste that instead for a definitive answer. - Does this check Poetry, Pipenv, or uv lockfiles?
- Not yet - today we read requirements.txt and the npm-ecosystem lockfiles. The practical workaround is to export:
poetry export -f requirements.txt,pipenv requirements, oruv export --format requirements-txt, then paste the result. - Does `pip-audit` or Safety already cover this?
- They mostly cover known vulnerabilities in legitimate packages, drawing on advisory databases. Deliberately malicious packages are usually yanked from PyPI within hours of discovery, and after that a vulnerability lookup often returns nothing while the malicious version is still pinned in your file and cached in your internal mirror. We match the malicious releases directly.
- I installed one of these. Is uninstalling enough?
- No. Assume anything readable by that process was taken - environment variables, API tokens, SSH keys, cloud credentials. Rotate them from a different machine, then uninstall and clear your pip cache and any internal mirror that may still be serving the yanked release.
Check another file
We only list package versions named by the original advisory - we don't infer compromises. Spotted one we're missing? Send it in.