DEV Community

Alex Spinov
Alex Spinov

Posted on

LiteLLM Was Just Compromised on PyPI — Here's How to Detect Supply Chain Attacks

What Happened

Today on Hacker News: LiteLLM versions 1.82.7 and 1.82.8 on PyPI are compromised.

This is a supply chain attack — malicious code injected into a legitimate package. If you installed these versions, your credentials may be exposed.

This Is Not New

Supply chain attacks happen constantly:

  • event-stream (2018) — 2M weekly downloads, maintainer handed off to attacker
  • ua-parser-js (2021) — cryptominer injected into 8M weekly download package
  • colors + faker (2022) — maintainer self-sabotaged in protest
  • LiteLLM (2026) — compromised PyPI release

How to Protect Yourself

Here's a practical detection script using only free APIs:

import requests
import json

def check_pypi_package(name):
    """Detect potential supply chain issues in a PyPI package."""
    data = requests.get(f"https://pypi.org/pypi/{name}/json").json()
    info = data.get("info", {})
    releases = data.get("releases", {})

    risks = []

    # Check 1: Recent maintainer email change
    author_email = info.get("author_email", "")

    # Check 2: Very recent release (within hours)
    versions = list(releases.keys())
    if versions:
        latest = versions[-1]
        files = releases[latest]
        if files:
            upload_time = files[0].get("upload_time", "")
            print(f"Latest: {latest} uploaded {upload_time}")

    # Check 3: Source repo mismatch
    project_urls = info.get("project_urls", {}) or {}
    home = info.get("home_page", "")
    if not home and not project_urls:
        risks.append("NO_SOURCE_REPO: no homepage or project URLs")

    # Check 4: Yanked versions (often indicates compromise)
    yanked = [v for v, files in releases.items() 
              if any(f.get("yanked", False) for f in files)]
    if yanked:
        risks.append(f"YANKED_VERSIONS: {yanked}")

    # Check 5: Suspiciously few maintainers
    maintainer = info.get("maintainer", "")
    author = info.get("author", "")
    if not maintainer and not author:
        risks.append("NO_MAINTAINER_INFO")

    return {
        "package": name,
        "version": info.get("version"),
        "risks": risks,
        "risk_level": "HIGH" if len(risks) >= 2 else "MEDIUM" if risks else "LOW"
    }

# Check your dependencies
for pkg in ["litellm", "requests", "flask", "django"]:
    result = check_pypi_package(pkg)
    print(f"\n{result['package']}: {result['risk_level']}")
    for risk in result["risks"]:
        print(f"  ⚠️ {risk}")
Enter fullscreen mode Exit fullscreen mode

npm Version (Same Concept)

def check_npm_package(name):
    """Detect supply chain risks in npm packages."""
    data = requests.get(f"https://registry.npmjs.org/{name}").json()
    versions = list(data.get("versions", {}).keys())
    maintainers = data.get("maintainers", [])

    risks = []

    if len(maintainers) == 1:
        risks.append(f"SINGLE_MAINTAINER: {maintainers[0].get('name', 'unknown')}")

    # Check for maintainer change in latest version
    if len(versions) >= 2:
        latest = data["versions"][versions[-1]]
        prev = data["versions"][versions[-2]]
        if latest.get("_npmUser", {}) != prev.get("_npmUser", {}):
            risks.append("PUBLISHER_CHANGED: different user published latest")

    # Check GitHub advisories
    advisories = requests.get(
        f"https://api.github.com/advisories",
        params={"ecosystem": "npm", "package": name}
    ).json()
    if isinstance(advisories, list) and advisories:
        risks.append(f"KNOWN_CVES: {len(advisories)} advisories")

    return {"package": name, "risks": risks}
Enter fullscreen mode Exit fullscreen mode

Prevention Checklist

  • Pin exact versions (== not >=)
  • Use lock files (poetry.lock, package-lock.json)
  • Enable Dependabot or Renovate (free on GitHub)
  • Review changelogs before updating major versions
  • Check maintainer changes on every update
  • Use pip install --require-hashes in production

Free Tools for Detection

Tool What It Checks
pip audit Known CVEs in Python deps
npm audit Known CVEs in Node deps
npms.io API Quality scores
GitHub Advisory DB CVEs by ecosystem
Socket.dev Supply chain analysis
PyPI JSON API Package metadata

Full scanner: npm-security-scanner
Python tools: python-security-tools


How do you protect against supply chain attacks? Share your workflow 👇

Top comments (0)