Konfirmity
All security advisories

//security advisory

LiteLLM 1.107.0 Supply Chain Compromise

On 21 October 2026 an attacker used LiteLLM’s own release pipeline to publish a malicious version 1.107.0 to PyPI and Docker. It ran every time Python started, collected cloud, AI provider and developer credentials, and sent them to the attacker. It was live for about two hours, and stolen credentials have already been used. If you installed it or ran an affected image, rotating secrets matters more than removing the package.

On this page
  1. Are you affected?
  2. What to do
  3. Affected releases
  4. Check your environment
  5. Clean up and rotate
  6. What the malware does
  7. Indicators of compromise
  8. How it happened
  9. Timeline
  10. Where the sources differ
  11. Recording it for compliance
  12. FAQ
  13. Sources

Are you affected by the LiteLLM compromise?

Only the 1.107.0 release on 21 October is malicious. Find the row that describes you.

  • You installed litellm 1.107.0 from PyPI

    pip, uv or Poetry between 11:39 and 13:23 UTC on 21 October, including unpinned installs and CI jobs

    Act now

    Treat the machine or runner as compromised. The theft happened when Python first started, so rotate every secret it could read. Clean up and rotate

  • You ran a LiteLLM Docker image from a floating tag

    latest, main-latest, main-stable or v1.107.0, pulled or restarted between 11:46 and 14:20 UTC on 21 October

    Act now

    Treat the container and the secrets passed to it as compromised. Redeploy pinned to a digest. Check the digest you ran

  • You run the LiteLLM proxy with a database

    The litellm-database image, or any deployment with DATABASE_URL set

    Act now

    If it ran the bad release, the malware queried the proxy database for its stored provider keys. Rotate every provider key, the master and virtual keys, and the database password.

  • You use LiteLLM through another package

    DSPy, langchain-litellm, llama-index-llms-litellm, Open Interpreter, Guardrails AI, or the litellm extra of CrewAI, smolagents and others

    Update needed

    Check your lockfile and install logs. You are affected only if the install resolved to 1.107.0 during the window. How to check

  • You pin LiteLLM to an earlier version or image digest

    Any version up to 1.106.2, or a digest you chose before 21 October

    Protected

    Not affected. LiteLLM says every earlier version is safe. Keep the pin until releases resume.

  • You use LiteLLM’s private enterprise registry

    Enterprise customers pulling from BerriAI’s private registry

    Protected

    Not affected, according to LiteLLM.

What to do

If 1.107.0 ran anywhere, assume its secrets are already with the attacker. Removing the package does not undo that.

  1. Find every place that ran 1.107.0

    Check developer machines, CI runners, containers and Kubernetes clusters. Include anything that pulled a floating Docker tag or installed LiteLLM without a pinned version. How to check
  2. Isolate it and keep the evidence

    Take the machine or container off the network, and save process, file and network evidence before you change anything. Do not start Python or pip in it: that runs the malware again.
  3. Rotate every secret it could read, from a clean machine

    Start with cloud roles and AI provider keys, which the attacker is already using. What to rotate
  4. Rebuild, then pin

    Rebuild environments and images from scratch with litellm==1.106.2, and pin Docker images by digest instead of a tag. Clean digests
  5. Look for use of stolen credentials

    Search cloud audit logs and network logs for the indicators below, especially AWS calls from unfamiliar IP addresses after 11:39 UTC on 21 October. Indicators

Affected releases

Times are UTC on 21 October 2026. All of these have been removed or pointed back at clean images.

Malicious LiteLLM artifacts and when they were live
ArtifactLiveNow
PyPI: litellm 1.107.0, all seven wheels11:39:51 to about 13:23 UTCRemoved by PyPI
GHCR: ghcr.io/berriai/litellm, litellm-database, litellm-non_root11:46:56 to 13:51 UTC at the latestRemoved
Docker Hub: docker.io/litellm/litellm11:46:56 to 14:20 UTCRemoved

On every registry the affected tags were v1.107.0, latest, main-latest and main-stable. A deployment that follows a floating tag could have pulled the bad image without anyone choosing 1.107.0. The source archive (sdist) carried the tampered build setting but not the malicious files.

Safe versions

LiteLLM says every earlier version is safe and tells users to pin litellm==1.106.2. Normal releases are paused while it investigates, so there is no newer clean release yet. The floating Docker tags now point to the 1.106.2 images. Pin these image index digests rather than a tag:

Clean LiteLLM 1.106.2 image index digests
Image1.106.2 index digest (sha256)
ghcr.io/berriai/litellm and docker.io/litellm/litellm7294b90f868c5c38c99b83021c7ba46f9b439e95f8e32964c925c7d2563a03f7
ghcr.io/berriai/litellm-database35f2cec3a14bb297e08bfab56c1fc377432bc4071aaf71978fdff043a5d91e79
ghcr.io/berriai/litellm-non_root07fabea33dfc2b127e865c03112dfc76936334b29028ec05cdd355af2385dc04

Clean digests are from issue #47826 and matched the registries on 22 October. Check them again before you deploy.

Check your environment

Run checks from a shell. Starting Python or pip inside a suspect environment, even to check a version, runs the malware again.

Installed packages

Look for the malicious files directly on disk. Any match means the environment ran, or will run, the malware.

Linux and macOS
# Run from a shell. Do not start Python or pip in a suspect environment.
find / -path '*-packages/litellm-1.107.0.dist-info' -type d 2>/dev/null
find / -path '*-packages/cook.pth' -type f 2>/dev/null

LiteLLM’s own report suggests pip show litellm, but also warns that any Python start runs the malware. Use pip only from a clean interpreter pointed at the suspect environment, or stick to the file checks above.

Lockfiles and install logs

Repository
# requirements files, and uv.lock or poetry.lock (which list wheel file names)
grep -rnE 'litellm(\[[^]]*\])? *(==|-) *1\.107\.0([^0-9a-z]|$)' .

Pre-releases such as 1.107.0rc1 and 1.107.0rc2 are reported clean. Pipfile.lock puts the version on a separate line, so open it and read the litellm entry. Unpinned installs leave no lockfile, so also search CI logs and package caches from 21 October for litellm-1.107.0.

Docker and Kubernetes

Docker
docker images --digests | grep -E 'berriai/litellm|litellm/litellm'
docker images --digests | grep -E '1bbcb1443bc9|c00f9d92c427|7b00e91cd2fe'
Kubernetes
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\t"}{.status.containerStatuses[*].imageID}{"\n"}{end}' \
  | grep -E '1bbcb1443bc9|c00f9d92c427|7b00e91cd2fe|bd1aeee419ea|56b74573eed6|24581ddc3076|827dd893c74c|645a67d81062|f75c8edae59b'

These show only images present now. A pod that ran the bad image and was replaced since leaves no trace here, so also check deployment history and registry pull logs for 11:46 to 14:20 UTC on 21 October. Inside a LiteLLM image the files sit in /app/.venv/lib/python3.13/site-packages/.

Signs the malware ran

Linux and macOS
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>/dev/null
lsof /tmp/remote_code_loader.lock
  • /tmp/.pc_once_72129118c59f5636c0bb means the stolen data was sent successfully.
  • A process holding /tmp/remote_code_loader.lock is the background loader still running.

A missing marker proves nothing. Failed uploads, temporary folder clean-up and container restarts all leave none behind.

Clean up and rotate

Rebuilding from scratch is safer than cleaning in place. If you must clean in place, do it from a shell, after saving evidence.

Shell
# 1. Stop the background loader
kill $(lsof -t /tmp/remote_code_loader.lock)

# 2. Remove the startup files (set SP to each affected site-packages folder)
SP=/path/to/site-packages
rm -f "$SP/cook.pth" "$SP/cook.py" "$SP/sitecustomize.py" \
  "$SP"/__pycache__/cook*.pyc "$SP"/__pycache__/sitecustomize*.pyc

Some systems ship a legitimate sitecustomize.py. Check its hash against the indicators before you delete it. Then reinstall litellm==1.106.2, and block 1.107.0 in any package proxy or mirror you run.

What to rotate

If 1.107.0 ran on a machine with internet access, assume the theft succeeded. Rotate from a clean machine, starting with what the attacker is known to use: cloud roles and AI provider keys.

Secrets to rotate after running LiteLLM 1.107.0
AreaWhat to rotate
Cloud identitiesAWS instance and task roles, the AWS, Azure and Google Cloud files in the home folder, and Kubernetes and Docker configs. The malware read cloud metadata services directly and checked AWS keys before sending them.
AI provider keysEvery key in the process environment, and every key stored in a LiteLLM proxy, plus its master key, virtual keys and salt key.
DatabasesThe DATABASE_URL password, and any connection string in .env files or the environment.
Code and package publishingGitHub CLI tokens, Git credentials, npm, PyPI, Cargo, Maven and other registry tokens, and SSH and GPG keys.
CI and infrastructureGitLab runner and Jenkins secrets, Vault tokens, Terraform credentials, and TLS private keys on the host.
AI coding toolsSessions and configs for Claude Code, Codex, Gemini CLI, Cursor, Copilot, Windsurf and similar tools, including MCP server configs that hold tokens.
Browsers on developer machinesSaved passwords and session cookies from Chrome, Edge, Brave, Firefox and other browsers. Sign out of important sessions and change those passwords.

What the malware does

The malicious release added three files at the top of the Python library folder. LiteLLM’s own code was not changed.

When it runs

Python reads .pth files and sitecustomize.py every time it starts. The release used both, so the malware ran whenever any Python program started in that environment, whether or not it imported LiteLLM: pip, pytest, a notebook, or the LiteLLM proxy itself. Installing the package did not run it; the next Python start did. According to Socket, the files were slipped in through one added line in the build configuration, which the official 1.107.0 tag does not contain.

What it collects

What the LiteLLM 1.107.0 malware collects
AreaWhat it takes
EnvironmentEvery environment variable of the Python process and, on Linux, of every other process it can read. This is how provider keys such as OPENAI_API_KEY and ANTHROPIC_API_KEY are taken.
LiteLLM proxy databaseWith DATABASE_URL set, it queries the proxy’s stored credentials and model settings, up to 500 rows of each.
CloudAWS, Azure and Google Cloud credential files and metadata services, ECS task credentials, Kubernetes service account tokens, and mounted container secrets.
Developer secrets.env files, Git, npm, PyPI and other registry credentials, SSH, GPG and TLS private keys, and key files under the home folder.
CI and infrastructureGitLab runner and Jenkins secrets, Vault tokens, and Terraform and Packer credentials.
AI toolsLogin files and configs for about 20 AI coding tools, including Claude Code, Codex, Gemini CLI, Cursor, Copilot and Hugging Face.
WorkstationBrowser passwords, cookies and history, shell and database client histories, and network details.

It encrypts everything with a key only the attacker can unlock and sends it to www.litellm.dev, a domain registered on 13 October that looks like LiteLLM’s own. Because the upload is encrypted, captured network traffic will not show what was taken.

The remote loader

The second file starts a hidden background process. Every hour it reads a small file from a GitHub repository to learn which server to contact, then downloads and runs whatever Python code that server returns, with no checks. The pointer file only ever held test values and has been empty since 20 October, and the account has since been taken down. No second stage has been seen, but a running loader would obey whoever controls that pointer, so stop it. On Windows the loader fails and only the theft runs.

Is it being exploited?

Yes. Wiz reports that from 16:20 to 17:01 UTC on 21 October the attacker tested AWS role credentials stolen from CI runners and Kubernetes nodes across multiple environments. Each was checked, then used to list the AI models available in Amazon Bedrock. That pattern points to LLMjacking: running AI models at the victim’s expense. In some environments the attacker also listed IAM users, roles and access keys and checked CloudTrail settings. No victim count or download count for 1.107.0 has been published.

Indicators of compromise

Domains are written with brackets so they cannot be clicked. Remove the brackets before you load them into a tool.

Network

  • Data upload: HTTP POST to hxxp://www[.]litellm[.]dev/healthcheck with the header X-Token: XWiA8gZNa7NcX2XRoAEb
  • Loader pointer: the GitHub repository letters9813/pythonclient-test, read through raw[.]githubusercontent[.]com
  • Second stage: any request to a path ending in /codepy
  • Python processes calling cloud metadata addresses 169.254.169.254 or 169.254.170.2
  • Stolen credentials used from 168.100.8[.]57 and 165.227.201[.]8 (Wiz)

litellm.dev sits behind Cloudflare, so block the domain, not its IP addresses. Block the GitHub repository path, not all of raw.githubusercontent.com.

In cloud audit logs

In AWS CloudTrail, look for sts:GetCallerIdentity from an instance or task role around the time 1.107.0 first ran, followed by use of the same role from outside your network, especially bedrock:ListFoundationModels and IAM listing calls.

On disk

  • cook.pth, cook.py or an unexpected sitecustomize.py at the top of site-packages, and their .pyc files
  • litellm-1.107.0.dist-info
  • /tmp/.pc_once_72129118c59f5636c0bb, /tmp/remote_code_loader.lock, and folders named /tmp/.pc_sq_* or /tmp/.pc_e_*
  • The environment variable PRIVCOLLECT_ACTIVE=1, and a detached Python process whose working folder is /

Wheel hashes (SHA-256)

SHA-256 hashes of the malicious litellm 1.107.0 wheels
litellm-1.107.0-cp310-abi3-…SHA-256
macosx_10_12_x86_64.whl7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d
macosx_11_0_arm64.whl0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a
manylinux_2_28_aarch64.whl668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6
manylinux_2_28_x86_64.whl462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7
musllinux_1_2_aarch64.whlc2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054
musllinux_1_2_x86_64.whl1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00
win_amd64.whl12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484
litellm-1.107.0.tar.gz (sdist)2befe2a79fb4fbbd9a543b5b40b530c8cffa8771bab22b8fb22b2e4ae3b1f819

Payload file hashes (SHA-256)

SHA-256 hashes of the malicious startup files
FileLinux and macOSWindows
cook.pth7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d
cook.py9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be2503ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea
sitecustomize.py34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fab6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465
All file hashes
7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d
0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a
668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6
462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7
c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054
1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00
12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484
2befe2a79fb4fbbd9a543b5b40b530c8cffa8771bab22b8fb22b2e4ae3b1f819
7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb
84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d
9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25
03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea
34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa
b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465

Container image digests (sha256)

Digests of the malicious LiteLLM 1.107.0 images
Imageamd64arm64
litellm (GHCR and Docker Hub)bd1aeee419ea36da9aa2b657288da4101887be468f020ac63d22ba6ed84a3ea556b74573eed6e4aafe4b50603dbe7853e0345f188c8e44a09f1098caf1f4bcdf
litellm-database24581ddc30767f16ecb69d2b0517556f2cd7dea56971adb42a3d1beb97d69523827dd893c74cf621a860a66a3a447a5c732533f087589ce905573e285c0a239c
litellm-non_root645a67d810628252d63df85dcc8824c58bcc77cf8383f4d3e6321f0ccc3ce9e4f75c8edae59b72b1ebfd617295833f465c85bb2fab9c1d60f21b496db86cb8da

The image index for litellm on GHCR and Docker Hub is 1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e. The index digests for litellm-database and litellm-non_root have only been published in part: c00f9d92c427… and 7b00e91cd2fe…. Hashes are from Socket, Wiz, SafeDep and the LiteLLM report.

How it happened

This is LiteLLM’s preliminary account. The maintainers say they are still confirming parts of it.

After an earlier compromise in March, LiteLLM moved releases to a private repository, published through PyPI’s trusted publishing, made Docker tags immutable and signed its images. Publishing was limited to one account tied to a laptop kept in the office. The attacker went around these controls rather than through them: with stolen credentials they ran LiteLLM’s own release pipeline, so the malicious release was built, signed and published like a normal one.

  • The attacker held GitHub CLI tokens for three LiteLLM engineers. One belonged to one of the two owners of LiteLLM’s GitHub organisation.
  • With the owner’s token they turned off branch protection and changed the release workflow so it could build from another repository.
  • They pointed it at Berri-AI/litellm, a lookalike of BerriAI/litellm that differs by one hyphen. A second account approved the release, and a third deleted the workflow records afterwards.
  • A permission change made the day before, to let two engineers ship daily fixes, widened who could release.

Where the tokens came from

LiteLLM found an unexpected, innocently named user account in its own internal LiteLLM deployment, which was reachable from the internet. It believes the attacker read the tokens from that deployment’s logs. LiteLLM says it has seen specific situations in which Claude Code puts a user’s GitHub CLI token into a response body, and where response bodies are logged, the token lands in LiteLLM’s logs. It has not published those situations, and at the time of writing we found no statement from Anthropic about this.

  • Unconfirmed: how the attacker got into the internal deployment. LiteLLM suspects a recently patched vulnerability but has not named it.
  • Unconfirmed: how the other two engineers’ tokens were obtained.
  • Unknown: who is behind it. No link to the March attack has been established, and JFrog treats them as separate campaigns.

The lesson applies beyond LiteLLM. An AI gateway’s logs can hold anything that passes through it, including tokens. Treat those logs as secret, limit who can reach them, and keep internal gateways off the public internet.

How LiteLLM is responding

LiteLLM revoked the tokens involved, removed all but one user from its GitHub organisation, cut the trusted links between public registries and GitHub, locked its registries and paused releases. It is rotating every token across the organisation. An unrelated embargoed security fix, due for disclosure on 27 October, is going only to its private enterprise registry.

Not the March 2026 incident

In March 2026 LiteLLM 1.82.7 and 1.82.8 were malicious for about 40 minutes, in an attack tied to the Trivy compromise. The October payload, infrastructure and way in are all different. The two incidents share one GitHub advisory and one OSV record, while the PyPA record PYSEC-2026-2 lists only the March versions. A scanner that relies on that record alone may not flag 1.107.0, so check the version directly.

Timeline

Times are UTC. The attacker prepared for at least a week before the release.

  1. 2026-10-13

    The domain litellm.dev is registered, and the GitHub account that later hosts the loader’s pointer file is created.

    GitHub issue #47826

  2. 2026-10-20

    LiteLLM temporarily widens release permissions so two engineers can publish daily bugfix backports.

    LiteLLM incident report

  3. 2026-10-21 · 08:56 UTC

    The attacker starts committing the malicious files to a lookalike repository, Berri-AI/litellm.

    GitHub issue #47826

  4. 2026-10-21 · 10:08 UTC

    Branch protection blocks a change to the private release workflow. Seconds later a privileged developer credential overrides it.

    LiteLLM incident report

  5. 2026-10-21 · 11:11 UTC

    A second developer’s credential approves the production release.

    LiteLLM incident report

  6. 2026-10-21 · 11:39 UTC

    Seven malicious litellm 1.107.0 wheels are uploaded to PyPI.

    LiteLLM incident report

  7. 2026-10-21 · 11:43 UTC

    Automated scanners begin flagging the wheels: AISLE at 11:43, Socket at 11:46.

    AISLE

  8. 2026-10-21 · 11:46 UTC

    The malicious Docker images are published, and floating tags such as latest start pointing to them.

    LiteLLM incident report

  9. 2026-10-21 · 11:53 UTC

    A third developer’s credential deletes the release workflow records, limiting the logs available to investigators.

    LiteLLM incident report

  10. 2026-10-21 · 12:06 UTC

    Upwind researcher Lidor Machluf reports the compromise publicly.

    GitHub issue #47826

  11. 2026-10-21 · 13:23 UTC

    PyPI has removed litellm 1.107.0.

    LiteLLM incident report

  12. 2026-10-21 · 13:50 UTC

    LiteLLM acknowledges the compromise and declares its top severity.

    GitHub issue #47826

  13. 2026-10-21 · 14:20 UTC

    All affected Docker Hub tags are removed or pointed back at clean images.

    LiteLLM incident report

  14. 2026-10-21 · 16:20 UTC

    Wiz sees the attacker testing stolen AWS role credentials and listing Amazon Bedrock models, until 17:01.

    Wiz

  15. 2026-10-21 · 16:32 UTC

    LiteLLM says the attacker used stolen GitHub CLI tokens belonging to three engineers.

    GitHub issue #47826

  16. 2026-10-21 · 21:46 UTC

    OpenSSF adds 1.107.0 to its malicious package record.

    OpenSSF malicious-packages

  17. 2026-10-21 · 23:37 UTC

    LiteLLM is rotating every token across its organisation. Registries stay locked and releases are paused.

    GitHub issue #47826

Where the sources differ

Reports written during the day disagree in places. Here is what each says and how we read it.

Points where sources disagree
QuestionWhat the sources sayOur reading
When PyPI removed it13:20 UTC (Wiz, Datadog); by 13:23 UTC (LiteLLM).Use 13:23. A few minutes do not change the advice: treat any install of 1.107.0 that day as compromised.
When the Docker images were removedAbout 13:53 UTC for all registries (Wiz, Datadog); GHCR by 13:51 and Docker Hub at 14:20 UTC (LiteLLM). StepSecurity uses 14:32 as a cautious end.Use 14:20 for Docker Hub. LiteLLM’s own check at 13:51 found Docker Hub still serving the bad image.
The clean version to pin1.106.2 (LiteLLM, Wiz, Datadog, Upwind); 1.106.0 (OX Security).Both are reported clean. Pin 1.106.2, the version LiteLLM names.
Whether the malware is compiled“Compiled malware” (LiteLLM); one layer of encoded and compressed Python source (Socket, StepSecurity, Endor Labs).It is Python that reads plainly once decoded. This does not change any remediation step.
Whether pip uninstall removes itYes, because the files are listed in the package record (StepSecurity); removing the package does not remove them (Socket, Endor Labs, Datadog).Running pip starts Python and runs the malware again. Delete the files from a shell, or rebuild.
What it stealsWiz lists Safari data and quotes a query that reads the whole credentials table.The decoded code has no Safari module and reads named columns. We follow the code as published by Socket and the issue thread.
How the attacker got inEarly reports guessed a stolen PyPI publishing token (AISLE, the original issue). LiteLLM later said it was stolen GitHub CLI tokens.Follow LiteLLM’s account, which it calls preliminary. Parts of it are unconfirmed.

OX Security names 1.106.0 as the clean version. Every other source, including LiteLLM, names 1.106.2.

Recording it for compliance

For most teams this is a supplier incident that may have exposed credentials. An auditor will ask how you found out, which systems ran the bad release, and what you rotated.

Controls to record this event against
FrameworkControlWhat to record
ISO 27001:2022A.5.21Managing security in the ICT supply chain. Record which systems pulled LiteLLM, how versions were pinned, and what you changed.
ISO 27001:2022A.8.7Protection against malware. Record the detection, removal and rebuild of each affected system.
ISO 27001:2022A.5.17Authentication information. Keep the list of secrets rotated, with dates.
ISO 27001:2022A.5.25, A.5.26, A.5.27Assess the event, respond to it, and record what you learned, such as moving to digest pinning.
ISO 42001A.10.3Suppliers of AI system components. LiteLLM sits between your systems and your AI providers.
SOC 2CC6.8Preventing and detecting malicious software.
SOC 2CC7.3, CC7.4Evaluating and responding to the incident.
SOC 2CC9.2Managing the risk of vendors and open source suppliers.
SOC 2CC6.1Revoking and reissuing exposed credentials.

Evidence to keep: when you assessed it, the systems, lockfiles and image digests you checked, what you found, the rebuilds, every secret rotated with its date, and the log review. If the malware ran where personal data was reachable, such as a proxy database holding customer prompts, assess whether you have a duty to notify.

For how these controls work day to day, see our guides to SOC 2 third-party risk, ISO 27001 third-party risk, SOC 2 secrets management, and incident response plans for ISO 27001 and SOC 2.

LiteLLM 1.107.0 compromise FAQ

Short answers. The sections above have the detail and sources.

What happened to LiteLLM 1.107.0?

On 21 October 2026 an attacker who held stolen developer credentials pointed LiteLLM's private release workflow at a lookalike repository, Berri-AI/litellm, and published the result as litellm 1.107.0 on PyPI and as LiteLLM's Docker images. The release added three files that run whenever Python starts and steal credentials. The official 1.107.0 source code on GitHub does not contain them.

Which LiteLLM versions are safe?

LiteLLM says every version before 1.107.0 is safe and tells users to pin litellm==1.106.2. Floating Docker tags such as latest now point to the 1.106.2 image again. Normal releases are paused while LiteLLM investigates, so there is no newer clean version yet.

Was I affected if I installed LiteLLM but never imported it?

Yes. The malicious files sit at the top of site-packages and Python runs them at startup, before any application code. Running pip, pytest, a Jupyter kernel or any other Python program in that environment was enough. Downloading the wheel without installing it was not.

Does uninstalling litellm 1.107.0 remove the malware?

Do not rely on it. Running pip starts Python, which runs the malware again, and deleting the litellm folder leaves the startup files behind. Stop the background process, delete the three files from a shell, or better, rebuild the environment or image from scratch. Removing the files does not undo the theft, so rotate secrets as well.

Which secrets should I rotate after the LiteLLM compromise?

Everything the affected machine or container could read. That includes cloud role and instance credentials, every AI provider key stored in a LiteLLM proxy along with its master and virtual keys, the proxy database password, environment variables, SSH and TLS keys, GitHub, npm and PyPI tokens, Kubernetes and Vault tokens, CI secrets, saved browser passwords, and logins for AI coding tools such as Claude Code, Codex, Gemini and Cursor.

Have the stolen LiteLLM credentials been used?

Yes. Wiz reports that between 16:20 and 17:01 UTC on 21 October the attacker tested AWS role credentials taken from CI runners and Kubernetes nodes, then listed the AI models available in Amazon Bedrock. That pattern points to an attempt to run AI models on the victim's account, known as LLMjacking.

Is this the same as the March 2026 LiteLLM compromise?

No. In March 2026 litellm 1.82.7 and 1.82.8 were briefly malicious, in an attack tied to the Trivy compromise. The October attack used a different payload, different infrastructure and a different way in, and no link between the two has been established. The two incidents share one GitHub and OSV advisory record, which adds to the confusion.

Is there a CVE for the LiteLLM 1.107.0 compromise?

No. A malicious release is not a code flaw, so no CVE has been assigned. It is tracked as GHSA-92x9-889m-jgmw in the GitHub Advisory Database and MAL-2026-2144 in OSV. The PyPA advisory PYSEC-2026-2 lists only the March versions, so scanners that rely on it alone may not flag 1.107.0.

Sources