Independent analysis by NHI Mgmt GroupSource article: Upwind, “LiteLLM 1.107.0 Supply Chain Attack: Malicious Code Found in PyPI Package” (October 21, 2026)

TL;DR: Malicious code in LiteLLM 1.107.0, a Python package on PyPI, can execute during interpreter startup, pull attacker-controlled payloads, and persist in affected environments, according to Upwind. Package compromise becomes a downstream credential theft path when runtime trust extends beyond installation checks.


At a glance

What this is: NHI Mgmt Group's analysis, drawing on Upwind's report: Malicious code in LiteLLM 1.107.0 uses Python startup hooks and persistence mechanisms to turn a PyPI package into a credential theft path.

Why it matters: This matters because package compromise can expose API keys, cloud credentials, mounted secrets, and workload identities that live inside the runtime context, not just in source control.


Context

A malicious package can become an execution path the moment Python starts, especially when startup hooks run before the application itself. In this case, the problem is not just package installation but the trust placed in the build and runtime environment around the package.

That risk becomes more serious when the package runs inside environments that already hold secrets, cloud workload identities, CI/CD credentials, or mounted pipeline identity controls. A compromised dependency is therefore an identity and secrets governance issue, not only a software supply chain issue.

The starting position here is atypical in its severity, but the failure mode is familiar: attacker code entered the distribution chain before defenders had a chance to judge the package by the published tag alone.


Key questions

Q: What should teams do first when a PyPI package is compromised?

A: Isolate the affected build and runtime hosts, block the compromised package version, and preserve process and network evidence before cleaning anything up. Then identify every environment that installed it, revoke any secrets exposed through install or post-install activity, and rebuild from trusted artefacts so you can confirm what executed and where.

Q: Why do Python startup hooks increase supply chain risk?

A: Python startup hooks increase supply chain risk because code can run automatically when the interpreter starts, before the application explicitly imports it. That gives a tampered package, site configuration, or environment path entry a route to execute with the process’s own permissions, often affecting every launch until the hook is removed or the environment is rebuilt.

Q: What should organisations do first when they suspect a malicious package could be executed in CI/CD?

A: The first priority is to reduce the blast radius of the pipeline. Use scoped credentials, validate artifacts, pin exact dependency versions, and enforce lockfiles and audit checks before execution. Then inspect the job for unexpected network calls, secret exposure, and drift in build behaviour. A pipeline should be treated as an attack surface, not just an automation layer.

Q: What are the signs that a dependency compromise is turning into credential theft?

A: Watch for Python processes reaching metadata endpoints, unexpected secret-store activity, new outbound JSON exfiltration, GitHub token misuse, and service persistence on developer endpoints. These signals indicate the package is moving from execution to collection and onward to externalised access.


Technical breakdown

Python startup hooks give malicious packages execution before imports

Python can execute code automatically during interpreter startup through mechanisms such as .pth processing and sitecustomize imports. Those hooks run before an application explicitly imports the package, which makes them attractive to supply chain attackers because the payload does not need an explicit call site. In this case, the package used startup-time execution to get code running inside the process boundary as soon as Python launched. That shifts the security question from whether an application imports the module to whether the interpreter itself can be induced to run attacker-controlled code. See the Malicious Package and Dependency Confusion Guide.

Practical implication: Treat interpreter-startup files as high-risk execution surfaces and inspect packages for code that runs before normal application imports.

Dynamic payload retrieval turns a package into a remote code loader

The package did not stop at local execution. It retrieved infrastructure information, requested additional code from attacker-controlled infrastructure, and compiled that response at runtime. That pattern makes the delivered payload mutable after installation, which means defenders cannot rely on a static package hash or a one-time review of the release artifact. The mechanism resembles a small loader rather than a fixed malware sample, with the remote server deciding what code runs next. In supply chain terms, this is a package that delegates execution to an external command path after deployment. See the AI Supply Chain Security and AI-BOM Guide.

Practical implication: Block unexpected outbound requests from build and runtime processes and hunt for packages that fetch code from remote infrastructure.

Persistence inside an application process expands credential exposure

The malicious code attempted to stay active by daemonizing, writing a lock file, and periodically checking back with attacker infrastructure. That is important because the longer attacker code lives inside the process environment, the more time it has to read environment variables, mounted secrets, local configuration, and any tokens the process can reach. In a runtime that already has access to cloud or LLM credentials, persistence converts a package incident into a broader identity and secrets event. The core architectural issue is that application processes often inherit more trust than they should once a dependency is allowed to execute inside them.

Practical implication: Assume any long-lived malicious dependency can reach everything the process can read and rotate exposed credentials immediately.


Threat narrative

Attacker objective: The objective is to gain durable code execution inside Python environments and use that access to steal secrets and extend control over affected systems.

  1. Entry occurred through a malicious PyPI release, with code placed into the build environment before the wheels were published.
  2. Credential harvesting followed once the package executed inside Python processes that could reach environment variables, mounted secrets, and workload credentials.
  3. Persistence came from daemon-like background behavior and repeated contact with attacker infrastructure, which kept the compromise alive after installation.
  4. Impact is the potential theft of cloud, API, application, and database credentials from environments that trusted the package to run normally.
  • LiteLLM supply chain attack 2026: Stolen GitHub CLI OAuth tokens let an attacker push malicious LiteLLM 1.107.0 to PyPI and Docker, stealing cloud, AI tool and LLM keys.
  • reviewdog Action compromise 2025: A stolen maintainer token poisoned reviewdog/action-setup, leaking CI secrets including the tj-actions bot token used in the next attack.

Read and download The State of NHI & AI Agent Breach Report 2026, covering 200+ breaches impacting Non-Human Identities including AI Agents.


NHI Mgmt Group analysis

Package trust has become runtime trust: supply chain control does not end when a wheel is published. When malicious code can run through interpreter startup hooks, the governance problem shifts from package approval to process-level execution authority. Practitioners should treat package provenance and runtime containment as a single control plane, not two separate reviews.

Secrets exposure is the real blast radius: the dangerous outcome is not the package compromise itself but what the compromised process can see. LLM provider keys, cloud workload identities, CI/CD tokens, and local configuration secrets all become reachable if they sit inside the same runtime context. The right question is no longer whether a dependency is known-good, but what privileges it inherits when it runs.

Build-stage tampering is a named concept worth tracking: malicious code injected before wheels are built creates a gap between the source tag and the shipped artifact. That gap undermines the assumption that reviewing repository content is enough to trust a release. Defenders should align provenance checks with build integrity, not just source inspection.

Persistent dependency compromise changes incident response scope: if attacker code phones home after installation, removal alone does not prove cleanup. The environment may still hold stolen secrets or altered runtime state, and those effects can survive beyond the package itself. Practitioners should treat recovery as both artifact removal and credential invalidation.

From our research library:

What this signals

Build-stage tampering is now a governance signal: defenders should track the gap between repository contents and shipped artifacts as a first-class supply chain metric. When malicious code is introduced before a wheel is built, source review alone is no longer enough to establish trust.

Python package compromise becomes an identity problem the moment the runtime can see secrets. That is why environment variables, mounted secrets, and workload credentials should be treated as part of the attack surface whenever a dependency can execute at interpreter startup.

When the package can keep phoning home, incident response must assume persistence and re-entry rather than a one-time script execution. Runtime containment, credential rotation, and artifact provenance belong in the same response plan.


For practitioners

  • Identify affected installations immediately Check every environment that may have installed LiteLLM 1.107.0 and confirm whether the affected wheels were present in development, CI/CD, or production systems.
  • Quarantine processes that loaded the package Isolate hosts where Python processes executed the package and preserve process, file, and network evidence before cleanup.
  • Rotate exposed secrets and workload credentials Refresh API keys, cloud credentials, mounted Kubernetes secrets, CI/CD credentials, and local configuration secrets reachable by the compromised process.
  • Review startup-time execution paths Search for .pth files, sitecustomize imports, and other interpreter hooks that can run code before application import logic.
  • Harden package and build provenance controls Require package provenance checks, pinned artifacts, and build isolation so injected code in the build chain is easier to detect before release.

Key takeaways

  • The incident shows how a published package can become an execution path before the application itself ever runs.
  • The exposed blast radius includes runtime secrets, cloud credentials, and workload identities reachable by the compromised process.
  • Provenance checks, runtime containment, and immediate credential rotation are the controls that limit this class of compromise.

Related NHI Mgmt Group resources: Malicious Package and Dependency Confusion Guide · AI Supply Chain Security and AI-BOM Guide · CI/CD Pipeline Identity Security Guide · LiteLLM supply chain attack 2026


Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP Non-Human Identity Top 10 and MITRE ATT&CK address the attack and risk surface, while NIST CSF 2.0 sets the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
OWASP Non-Human Identity Top 10NHI-02 — Secret LeakageThe malicious package can expose secrets reachable by the Python process.
NHI-07 — Long-Lived SecretsPersistent background behavior increases the window in which secrets can be stolen.
NHI-03 — Vulnerable Third-Party NHIA third-party package behaved as a trusted component inside sensitive environments.
Recommendation — Scan package runtimes for secret exposure paths and revoke any credentials reachable by compromised dependencies. Shorten secret lifetimes and rotate credentials immediately after dependency compromise. Treat third-party packages with delegated runtime access as governed identities with explicit trust boundaries.
MITRE ATT&CKTA0006; TA0011 — Credential Access; Command and ControlThe attack chain includes credential theft and repeated contact with attacker infrastructure.
Recommendation — Map package compromise to credential access and command-and-control detections in your monitoring stack.
NIST CSF 2.0PR.AA-05 — Access Permissions, Entitlements and AuthorizationsCompromised dependencies inherit whatever runtime access permissions the environment grants them.
Recommendation — Restrict process entitlements so packages cannot reach secrets or services they do not need.

Key terms

  • LiteLLM Supply Chain Attack: A LiteLLM supply chain attack is a compromise of the software distribution, dependency chain, or update path used to deliver LiteLLM components. In NHI and AI environments, this can expose secrets, alter agent behavior, or redirect model requests by tampering with code, packages, containers, or build artifacts.
  • Python .pth Mechanism: A Python .pth mechanism is a site initialisation feature that lets the interpreter add paths, and in some cases execute import statements, when it starts. It is used to extend module search locations, but a malicious or altered .pth file can trigger code execution early in startup and influence which packages load.
  • Remote Code Loader: A remote code loader is a program or component that retrieves and runs code from a remote location. In security terms, it acts as a delivery mechanism for later payloads, so the initial file may look small or benign while the real behaviour is fetched at runtime over the network.
  • sitecustomize.py (Python Startup Hook): sitecustomize.py is a Python startup hook that Python imports automatically when the interpreter starts, if it is present on the import path. Attackers can place malicious code there to gain persistence or influence every Python session. Defenders should restrict writable paths, inspect import locations, and watch for unexpected code in startup files.

Deepen your knowledge

NHI Foundation Level course, the industry's only accredited NHI security programme, covers NHI governance, machine identity security, and secrets management. It helps practitioners connect runtime identity controls to supply chain and operational risk.
NHIMG Editorial Note
Published by the NHIMG editorial team on November 9, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org