{"slug": "the-poisoned-litellm-1-107-0-problem-and-the-30-second-check-i-now-run-on-every", "title": "The poisoned LiteLLM 1.107.0 problem, and the 30-second check I now run on every repo", "summary": "A developer released litellm-check, an open-source scanner that automates detection of the compromised LiteLLM v1.107.0 release, which shipped malicious PyPI wheels, poisoned Docker tags and GHCR images on Oct 21. The tool runs 13 rules mapped to LiteLLM's official incident guidance, checking dependency specs, lockfiles, image tags and digests, installed package metadata, and persistence artifacts such as cook.pth and /tmp/remote_code_loader.lock, and can act as a CI gate via --fail-on critical. The developer cautions that a clean scan only means no known indicators were found, not that an environment is safe.", "body_md": "On Oct 21, LiteLLM disclosed that v1.107.0 shipped compromised — malicious wheels on PyPI (live 11:39–13:23 UTC), poisoned Docker tags (`v1.107.0`, `latest`, `main-latest`, `main-stable`, 11:46–14:20 UTC), and GHCR images (until 13:51 UTC). The official announcement: [https://docs.litellm.ai/blog/security-incident-oct-21-2026](https://docs.litellm.ai/blog/security-incident-oct-21-2026)\n\nThe part that caught people off guard: in an affected environment, *any* Python start re-runs the implant. So the vendor's own response steps warn you **not** to start with `pip install` or `pip show` on a suspect box — you check files and metadata first, from the shell.\n\nI turned the announcement's manual steps into a small checklist I now run on every repo and venv folder. Here's the method, then the tool that automates it.\n\n`litellm==1.107.0` pinned = exposed. But `litellm>=1.0`, `~=1.107`, `^1.107.0`, or unpinned `litellm` in requirements/pyproject/Poetry files = `poetry.lock`, `uv.lock`, `Pipfile.lock` for a resolved `v1.107.0` = exposed; `latest` / `main-latest` / untagged images pulled during Oct 21 11:46–14:20 UTC = suspect. Also compare against the compromised image digest published in the announcement.`litellm-*.dist-info/METADATA` directly in site-packages. If it says 1.107.0, treat the environment as compromised: rebuild from `litellm==1.106.2`, rotate every secret that box could reach, check CloudTrail.`cook.pth`, `cook.py`, a planted `sitecustomize.py`, and `/tmp/remote_code_loader.lock` (the C2 daemon ran or is still running if that lockfile exists).\nI packaged the above as `litellm-check` (13 rules, each mapped to a step in the official announcement), because I kept seeing \"how do I know if I was exposed?\" in issue threads:\n\n```\npip install litellm-check\nlitellm-check scan ./your-project        # code side\nlitellm-check scan ~/.virtualenvs        # installed-env side\n```\n\nOutput is a Markdown or JSON evidence report — file:line, the matched spec/tag, and the announcement basis for each finding. `--fail-on critical` works as a CI gate. Zero third-party dependencies, Python 3.11+, Apache-2.0.\n\n**The honest limit, printed on every report:** a clean scan means \"none of the known indicators were found\" — nothing more. Environments rebuilt after exposure, images pulled without a definition file in the tree, or CI-only installs leave nothing on disk to find. This is evidence collection, not a safety certification.\n\nIf your stack exposes LiteLLM somewhere these 13 rules miss, rule PRs with fixtures are the most useful contribution.", "url": "https://wpnews.pro/news/the-poisoned-litellm-1-107-0-problem-and-the-30-second-check-i-now-run-on-every", "canonical_source": "https://dev.to/xm-yang/the-poisoned-litellm-11070-problem-and-the-30-second-check-i-now-run-on-every-repo-570c", "published_at": "2026-10-23 00:05:54+00:00", "updated_at": "2026-10-23 00:12:02.811757+00:00", "lang": "en", "topics": ["ai-tools", "ai-infrastructure", "developer-tools", "ai-safety"], "entities": ["LiteLLM", "PyPI", "GHCR", "litellm-check", "Docker"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/the-poisoned-litellm-1-107-0-problem-and-the-30-second-check-i-now-run-on-every", "markdown": "https://wpnews.pro/news/the-poisoned-litellm-1-107-0-problem-and-the-30-second-check-i-now-run-on-every.md", "text": "https://wpnews.pro/news/the-poisoned-litellm-1-107-0-problem-and-the-30-second-check-i-now-run-on-every.txt", "jsonld": "https://wpnews.pro/news/the-poisoned-litellm-1-107-0-problem-and-the-30-second-check-i-now-run-on-every.jsonld"}}