Skip to main content
  1. Posts/

Supply Chain Attacks: LiteLLM, PyPI, and Axios

Ender
Author
Ender
Cybersecurity pro by day, gamer and storyteller by night. I write about breaking systems, exploring worlds, and the tech that powers it all.
Table of Contents

You Run Code You Didn’t Write
#

I want to talk about something that happened in the last couple of weeks, because I think it’s going to change how a lot of us think about pip install and npm install.

Three supply chain attacks hit the open-source package world back to back. LiteLLM got backdoored through its own CI/CD security scanner. PyPI has been getting hammered by typosquatting campaigns so severe the registry had to shut down new signups entirely. And Axios (the HTTP client that half of JavaScript depends on) got owned by a North Korean state-sponsored hacking group that social-engineered a maintainer’s account.

I’m going to walk through each one, because the technical details matter. The patterns connecting them matter more.

LiteLLM: They Compromised the Security Tool First
#

Timeline: March 24, 2026 CVE: CVE-2026-33634 (CVSS 9.4 Critical) Affected versions: litellm 1.82.7 and 1.82.8

If you’re not familiar with it, LiteLLM is an open-source Python library that proxies requests across LLM APIs. OpenAI, Anthropic, Cohere, all of them through a single interface. It pulls roughly 95 million downloads per month from PyPI. According to Wiz’s telemetry, it shows up in 36% of the cloud environments they monitor.

On March 24 at 10:39 UTC, two malicious versions appeared on PyPI. LiteLLM’s own blog says PyPI quarantined them in about 40 minutes, but Wiz’s forensic timeline puts the window closer to 3 hours. Either way, at 3.4 million downloads per day, a lot of people pulled bad code.

How They Got In
#

A threat group called TeamPCP didn’t target LiteLLM directly. They went after Trivy, the open-source security scanner maintained by Aqua Security. TeamPCP compromised a Trivy GitHub Action that ran in LiteLLM’s CI/CD pipeline and used it to steal the maintainer’s PyPI publishing credentials.

They compromised a security tool to get into the thing that security tool was supposed to be protecting. The same campaign also hit Checkmarx KICS and Telnyx.

What the Malware Did
#

Version 1.82.7 was straightforward. Base64-encoded payload injected into litellm/proxy/proxy_server.py.

Version 1.82.8 was worse. It dropped a .pth file (litellm_init.pth) into Python’s site-packages. If you’ve never dealt with .pth files: they execute on every Python interpreter startup. No import needed. Python starts, the malware runs. You didn’t even have to touch litellm in your code.

The payload operated in three stages:

  1. Exfiltration. SSL/SSH keys, cloud credentials, Kubernetes configs, Git credentials, API keys, shell history, crypto wallets.
  2. Reconnaissance. Environment mapping and further credential harvesting.
  3. Persistence. A systemd backdoor that polled for additional payloads, plus Kubernetes lateral movement.

Think about what LiteLLM is for a second. Its entire job is routing API keys for multiple AI providers. Every deployment concentrates those credentials in one place. Compromise that and you get every AI service key the org is running.

What to Do
#

If you ran 1.82.7 or 1.82.8: treat the system as fully compromised. Rotate every secret and credential. Audit for systemd persistence and unauthorized cron jobs. The last clean version is 1.82.6.

PyPI: The Flood That Won’t Stop
#

LiteLLM was a scalpel: one high-value target, compromised through its own build pipeline. The broader PyPI story looks more like a fire hose.

March 2024: The Registry Shut Down
#

On March 28, 2024, PyPI halted all new user registrations and project creation for about 10 hours. Over 500 malicious packages had been uploaded from unique accounts in an automated typosquatting campaign going after popular ML libraries. PyTorch, Matplotlib, Selenium.

The payload stole crypto wallets, browser cookies and extensions, and credentials. It survived reboots.

When a package registry has to freeze its own front door because it can’t keep up with the incoming malware, that’s worth sitting with for a minute.

Ultralytics: Twice in Four Days
#

In December 2024, Ultralytics (the YOLO object detection framework, with roughly 60 million PyPI downloads at the time) got hit twice.

December 4-5: An attacker using the handle “openimbot” opened PRs in the Ultralytics actions repository with injection payloads embedded in branch names, a “Pwn Request” attack. This was a vulnerability that researcher Adnan Khan had previously disclosed. The resulting malicious versions 8.3.41 and 8.3.42 shipped an XMRig crypto miner.

December 7: The attacker came back. This time they bypassed GitHub Actions entirely and published versions 8.3.45 and 8.3.46 directly to PyPI. Fixing the first vector wasn’t enough. The attacker had already pivoted.

It Keeps Going
#

A partial list of what else has been hitting PyPI:

DatePackage/CampaignTechniqueImpact
Feb 2025deepseeek, deepseekaiTyposquatting DeepSeek AI36 downloads in 30 min
Jul-Aug 2025sisaws, secmeasureSilentSync RAT via typosquatting800+ downloads
Late 202520 packagesCloud credential theft campaign14,100+ downloads
Mar 2026telnyx 4.87.1, 4.87.2TeamPCP maintainer compromiseSame campaign as LiteLLM

And there’s the Lazarus Group cross-platform campaign active since 2025, deploying malicious packages across both npm and PyPI at the same time. North Korean state actors operating on two fronts.

What PyPI Is Doing About It
#

Mandatory 2FA for critical projects, automated malware scanning, a quarantine system. These work. LiteLLM was quarantined within hours and a lot of typosquatting gets caught quickly. But when attackers are spinning up hundreds of accounts and publishing hundreds of packages in one campaign, even fast detection means some get through.

Axios: A Nation-State Goes After npm
#

Timeline: March 30-31, 2026 Affected versions: axios 1.14.1 and 0.30.4 Attack window: ~3 hours (00:21-03:20 UTC, March 31) Attribution: UNC1069 / Sapphire Sleet (North Korean state-sponsored)

Axios is one of the most depended-on packages in JavaScript. Over 174,000 npm packages depend on it. It gets over 100 million downloads per week.

The Sequence
#

On March 30 at 23:59 UTC, a package called plain-crypto-js@4.2.1 appeared on npm, a typosquat of the legitimate crypto-js. Twenty-two minutes later, axios@1.14.1 dropped. The only change: a new dependency on plain-crypto-js.

The attacker had compromised the npm account of jasonsaayman, one of the primary Axios maintainers. The account email was changed to an attacker-controlled Proton Mail address. Google’s Threat Intelligence Group attributed it to UNC1069. Microsoft independently attributed it to Sapphire Sleet. Both names for a North Korean state-backed group active since at least 2018.

The Payload
#

plain-crypto-js ran a postinstall script that deployed WAVESHAPER.V2, a cross-platform RAT with C++ (macOS), PowerShell (Windows), and Python (Linux) variants. After execution, the malware deleted itself and swapped its package.json for a clean copy. Anti-forensics built right into the install.

The technique was smart: by adding a dependency rather than editing Axios’s source, the diff was tiny. You could look at Axios’s code and see nothing wrong. The actual malware lived one level down.

Why Semver Made It Worse
#

If your package.json had "axios": "^1.14.0", any npm install during those 3 hours resolved to 1.14.1 automatically. That’s how semver caret ranges work. ^1.14.0 means “anything compatible up to 2.0.0.” It’s a feature. It’s also why, with 100 million weekly downloads, a 3-hour window at Axios’s download velocity means a staggering number of bad installs.

The attacker published 0.30.4 too, covering anyone on the legacy branch.

How Fast Was Detection?
#

Socket flagged plain-crypto-js within 6 minutes of publication, at 00:05:41 UTC. That’s genuinely fast. But Huntress observed the first endpoint infection just 89 seconds after the malicious version was published. The packages weren’t fully removed until about 03:20 UTC.

If you installed 1.14.1 or 0.30.4: downgrade to 1.14.0 (or 0.30.3), nuke node_modules/plain-crypto-js, and rotate every credential on the system.

What Connects These
#

Five things stand out when you look at these together.

CI/CD is the new perimeter. LiteLLM got popped through a GitHub Action. Ultralytics through GitHub Actions script injection. Neither was a direct credential theft. Both came through the build pipeline. Attackers aren’t targeting your code anymore. They’re targeting the tools that build, test, and publish your code.

Nation-states are in the package registries now. Axios was North Korea. The Lazarus Group campaign hits both npm and PyPI. This isn’t teenagers typosquatting. It’s state-sponsored teams with budgets and operational security.

The AI stack is a fat target. LiteLLM aggregates API keys. Ultralytics runs in production ML pipelines. Even the DeepSeek typosquats went after AI hype. If you concentrate credentials behind one library, compromising that library gets you everything downstream.

Semver ranges multiply impact. A 3-hour window plus 100M weekly downloads plus caret ranges means everybody running npm install in that window got malware by default. Same with pip install litellm resolving to the latest version.

And detection is outrunning remediation. Socket caught the Axios attack in 6 minutes. PyPI quarantined LiteLLM within hours. But the malware was designed to outlive its own delivery mechanism. Systemd backdoors, self-deleting payloads. Finding the package fast doesn’t help if the payload already entrenched itself on the host.

What I’d Actually Recommend
#

Pin your dependencies. Exact versions. 1.14.0, not ^1.14.0. Commit your lockfiles. Yes, you’ll do more manual updating. The alternative is trusting that every future version is safe by default, and that assumption just got demolished.

Audit your CI/CD actions. Pin GitHub Actions to commit SHAs, not tags. Tags can be moved. The LiteLLM attack came through a GitHub Action that everyone assumed was safe because it was a security tool.

Run a package firewall. Socket, Snyk, Sonatype, something that inspects packages before they hit your build. Socket caught the Axios dependency in 6 minutes. If that check ran in CI before npm install, you’d have been fine.

Turn on 2FA on everything. Package registry accounts, CI platforms, source control. The Axios attack started with a compromised maintainer account. 2FA isn’t foolproof against social engineering, but it raises the bar.

Watch for new transitive dependencies. The Axios attacker added plain-crypto-js as a dependency rather than editing source. Your diff tools should scream when a new transitive dependency shows up out of nowhere.

If you get hit, treat it as a full system breach. Don’t just uninstall and move on. Both LiteLLM and Axios payloads were designed to persist after the package was removed. Rotate credentials. Check for backdoors. Assume the worst until you can prove otherwise.

Build in disposable environments. Ephemeral containers, throwaway CI runners. If the build environment gets torched after every run, persistence mechanisms have nowhere to live.

Where This Is Going
#

The trust model that open source runs on (maintainers publish, developers install, registries try to keep things clean) worked for a long time. It’s now being stress-tested by state actors with social engineering teams, threat groups that turn security tools into attack vectors, and automated campaigns that can flood a registry with hundreds of poisoned packages in an afternoon.

The detection side is getting better. But the gap between “detected” and “safe” is where these attacks live. Three hours for LiteLLM. Three hours for Axios. Six minutes to flag, 89 seconds to infect.

Your dependency hygiene is the only part of this you control. Treat it accordingly.

Related

Words of Radiance, an Instant Top 10 Epic Fantasy

The long anticipated sequel and book 2 of the Stormlight Archive hit stores march 4th. It picks up right were we left off, the assassin in white has decapitated the leadership of Roshar and targets Dalinar Kholin the blackthorn and true power behind the Alethi kingship. While the first book of any epic fantasy series needs to build the world, the second book needs to make us care about the characters. If you have read fantasy for long enough nearly everyone reads “this big book that goes nowhere.” The second book in the series needs to be paced particularly well to keep the reader engaged and show significant character development. Words of Radiance has it in spades.