{
  "schemaVersion": "guard-threat-campaign/v1",
  "id": "HGTC-2026-385E1963",
  "slug": "litellm-1-107-0-supply-chain-compromise-credential-stealer",
  "title": "LiteLLM 1.107.0 shipped a credential stealer on PyPI and the Docker latest tag",
  "aliases": [
    "litellm 1.107.0",
    "LiteLLM supply chain compromise October 2026",
    "cook.pth",
    "privcollect",
    "ghcr.io/berriai/litellm:latest"
  ],
  "summary": "All seven litellm 1.107.0 wheels uploaded to PyPI at 11:39 UTC on 2026-10-21 contained three extra files under litellm-1.107.0.data/purelib/ (cook.pth, cook.py, sitecustomize.py) that pip installs into site-packages root. cook.pth imports cook.py at every Python start; it collects host info, browser passwords, SSH and cloud credentials, CI and registry tokens, AI tool configs, other processes' environments and, when DATABASE_URL is set, LiteLLM's credential and model tables, then POSTs an encrypted bundle to www.litellm.dev. sitecustomize.py adds an hourly remote-code loader keyed off a GitHub dead-drop file. The v1.107.0 git tag is clean; the sdist pyproject.toml carries an injected maturin data = \"cook\" line. PyPI removed 1.107.0. The Docker v1.107.0 image and the floating latest, main-latest and main-stable tags on GHCR and Docker Hub share digest sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e and still resolved to it at 13:44 UTC.",
  "status": "published",
  "severity": "critical",
  "confidence": "high",
  "uncertainty": "Payload analysis comes from AISLE and the public incident report (issue #47826). The claim that the release was built from the lookalike repository Berri-AI/litellm is the reporter's finding, not yet confirmed by BerriAI. HOL verified registry tag digests directly but did not unpack the Docker image. Number of affected installs is unknown.",
  "firstObservedAt": "2026-10-21T11:39:51Z",
  "lastObservedAt": "2026-10-21T13:44:00Z",
  "publishedAt": "2026-10-21T13:50:46.653Z",
  "reviewedAt": "2026-10-21T13:50:35.539Z",
  "expiresAt": "2026-10-21T13:44:00Z",
  "reviewer": "HOL Guard Security Publishing",
  "sources": [
    {
      "id": "aisle",
      "label": "AISLE: Compromised LiteLLM package found 3 minutes after release",
      "url": "https://aisle.com/blog/litellm-11070-on-pypi-shipped-a-credential-stealer",
      "sourceType": "research",
      "observedAt": "2026-10-21T00:00:00Z"
    },
    {
      "id": "issue",
      "label": "BerriAI/litellm issue #47826: litellm 1.107.0 compromised",
      "url": "https://github.com/BerriAI/litellm/issues/47826",
      "sourceType": "other_primary",
      "observedAt": "2026-10-21T13:24:25Z"
    },
    {
      "id": "release",
      "label": "LiteLLM v1.107.0 GitHub release",
      "url": "https://github.com/BerriAI/litellm/releases/tag/v1.107.0",
      "sourceType": "other_primary",
      "observedAt": "2026-10-21T11:50:24Z"
    },
    {
      "id": "pypi",
      "label": "PyPI litellm release history",
      "url": "https://pypi.org/project/litellm/",
      "sourceType": "other_primary",
      "observedAt": "2026-10-21T13:44:00Z"
    },
    {
      "id": "dockerhub",
      "label": "Docker Hub litellm/litellm tags",
      "url": "https://hub.docker.com/r/litellm/litellm/tags",
      "sourceType": "other_primary",
      "observedAt": "2026-10-21T13:44:00Z"
    }
  ],
  "artifacts": [
    {
      "id": "litellm-pypi",
      "artifactClass": "package",
      "ecosystem": "pypi",
      "name": "litellm",
      "version": "1.107.0",
      "defanged": false
    },
    {
      "id": "litellm-docker",
      "artifactClass": "package",
      "ecosystem": "docker",
      "name": "ghcr.io/berriai/litellm",
      "version": "v1.107.0, latest, main-latest, main-stable @ sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e",
      "defanged": false
    }
  ],
  "indicators": [
    {
      "id": "exfil-domain",
      "indicatorType": "domain",
      "value": "www[.]litellm[.]dev",
      "defanged": true,
      "confidence": "high"
    },
    {
      "id": "deaddrop-url",
      "indicatorType": "url",
      "value": "hxxps://raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt",
      "defanged": true,
      "confidence": "high"
    },
    {
      "id": "docker-digest",
      "indicatorType": "file_hash",
      "value": "1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e",
      "defanged": false,
      "confidence": "high"
    },
    {
      "id": "whl-manylinux-x86_64",
      "indicatorType": "file_hash",
      "value": "462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7",
      "defanged": false,
      "confidence": "high"
    },
    {
      "id": "whl-manylinux-aarch64",
      "indicatorType": "file_hash",
      "value": "668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6",
      "defanged": false,
      "confidence": "high"
    },
    {
      "id": "whl-musllinux-x86_64",
      "indicatorType": "file_hash",
      "value": "1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00",
      "defanged": false,
      "confidence": "high"
    },
    {
      "id": "whl-musllinux-aarch64",
      "indicatorType": "file_hash",
      "value": "c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054",
      "defanged": false,
      "confidence": "high"
    },
    {
      "id": "whl-macos-x86_64",
      "indicatorType": "file_hash",
      "value": "7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d",
      "defanged": false,
      "confidence": "high"
    },
    {
      "id": "whl-macos-arm64",
      "indicatorType": "file_hash",
      "value": "0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a",
      "defanged": false,
      "confidence": "high"
    },
    {
      "id": "whl-win-amd64",
      "indicatorType": "file_hash",
      "value": "12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484",
      "defanged": false,
      "confidence": "high"
    }
  ],
  "timeline": [
    {
      "id": "deaddrop-repo",
      "occurredAt": "2026-10-18T00:00:00Z",
      "eventType": "other",
      "summary": "GitHub repository hosting the stage-2 dead-drop file is created.",
      "sourceIds": [
        "aisle"
      ]
    },
    {
      "id": "pypi-upload",
      "occurredAt": "2026-10-21T11:39:51Z",
      "eventType": "first_observed",
      "summary": "litellm 1.107.0 wheels with credential stealer uploaded to PyPI.",
      "sourceIds": [
        "aisle",
        "issue"
      ]
    },
    {
      "id": "aisle-flag",
      "occurredAt": "2026-10-21T11:43:05Z",
      "eventType": "disclosure",
      "summary": "AISLE dependency firewall flags the first malicious wheel.",
      "sourceIds": [
        "aisle"
      ]
    },
    {
      "id": "docker-tags",
      "occurredAt": "2026-10-21T11:48:07Z",
      "eventType": "other",
      "summary": "Docker latest, main-latest and main-stable tags move to the v1.107.0 image digest.",
      "sourceIds": [
        "dockerhub",
        "issue"
      ]
    },
    {
      "id": "issue-opened",
      "occurredAt": "2026-10-21T12:06:41Z",
      "eventType": "disclosure",
      "summary": "Public incident report opened on BerriAI/litellm.",
      "sourceIds": [
        "issue"
      ]
    },
    {
      "id": "pypi-removed",
      "occurredAt": "2026-10-21T13:23:00Z",
      "eventType": "registry_action",
      "summary": "PyPI has removed 1.107.0; latest resolves to 1.106.2. Docker floating tags still point at the infected digest.",
      "sourceIds": [
        "issue",
        "pypi"
      ]
    }
  ],
  "coverage": [],
  "policies": [],
  "limitations": [
    "Installs pinned to 1.106.2 or earlier, and Docker images pinned to version tags other than v1.107.0, are reported clean",
    "The 1.107.0 sdist lacks the payload files though its pyproject.toml is tampered",
    "Installs after PyPI removal resolve to 1.106.2",
    "This is not a remotely exploitable flaw in LiteLLM code; impact is on machines that installed the poisoned build",
    "A passing cosign verify on the v1.107.0 image is not evidence of a clean image"
  ],
  "correctionHref": "/guard/security/campaigns/litellm-1-107-0-supply-chain-compromise-credential-stealer/corrections"
}
