Mini Shai-Hulud Supply-Chain Attack: What Site Owners and Dev Teams Need to Audit Now

Holographic robot inspecting package versions on a developer monitor, supply-chain attack audit concept

Written by

in

Between May 11 and May 12, 2026, a coordinated software supply-chain compromise infected official Mistral AI SDKs on both npm and PyPI, plus three core TanStack JavaScript libraries. The injected code harvested developer secrets, opened a backdoor for credential theft, and shipped a destructive payload that could wipe Linux hosts. Anyone shipping production code through automated pipelines needs to treat this as an active incident on their own infrastructure.

The campaign used trusted, widely downloaded packages as the entry point. That makes reputation-based allowlists and casual lockfile reviews useless as a defense. Below is a walk-through of how the attack worked, what to grep for in your own projects, and the structural changes worth making before the next wave hits.

How a Trusted Package Became the Entry Point

Two parallel waves struck during a 24-hour window. The first wave, beginning around 19:20 UTC on May 11, republish ed several TanStack packages with injected code: @tanstack/react-router, @tanstack/history, and @tanstack/router-core. These libraries sit underneath thousands of React routing implementations, and each is downloaded tens of millions of times per week.

Within hours, the same operator compromised three Mistral AI npm SDKs: @mistralai/mistralai, @mistralai/mistralai-azure, and @mistralai/mistralai-gcp. On the Python side, version 2.4.6 of the mistralai package on PyPI was trojanized. The attack vector was identical in each case: legitimate maintainer or publisher credentials were used to push a new version containing hostile code, so the registry itself treated the upload as authentic.

What the Payload Actually Did on Linux Hosts

The mistralai PyPI trojan embedded its code directly in mistralai/client/__init__.py, a module that runs the moment any downstream script imports the package. On Linux systems, the injected code issued a curl request to the command-and-control host at 83.142.209.194 and saved the response to /tmp/transformers.pyz. The filename was chosen to mimic Hugging Face’s Transformers library, so the dropped file blends into the typical noise of an AI development workstation.

Once executed, the second-stage payload detached from the parent Python process and ran independently in the background. It scanned the host for high-value secrets: GitHub personal access tokens, npm publishing tokens, cloud provider API keys, SSH keys, and CI/CD environment variables. All visible errors were suppressed, which is why no install script ever raised a warning.

Two details make this payload worse than a typical stealer. First, it contains logic that checks the system locale and exits without doing anything on Russian-language Linux installs, a pattern consistent with financially motivated actors filtering out their own geography. Second, a destructive branch can issue rm -rf / under certain geographic conditions, irreversibly wiping any host it reaches.

Indicators of Compromise Worth Hunting For

Start with the artifacts the analysts have already named. The dropped payload lives at /tmp/transformers.pyz on Linux. Watch for outbound traffic to 83.142.209.194 from build runners, developer laptops, and any container that ever installed one of the affected packages. Microsoft Threat Intelligence has also flagged two additional artifacts that may appear on hosts that ran the second stage: pgmonitor.py and pgsql-monitor.service. Treat both as high-confidence signals of compromise and rotate everything those hosts touched.

Beyond those named indicators, run a focused review of any process that detached from a Python or Node.js install script and is still running in the background. Cross-reference process start times against the exact install windows for the compromised package versions.

The Audit Checklist for Your Own Dependency Tree

The compromised packages are not obscure transitive dependencies. They are flagship SDKs and routing libraries that pass every reputation check a typical allowlist runs. That is exactly why a manual review is the only reliable defense right now. Walk through these steps in order.

  • Grep every package.json, pnpm-lock.yaml, yarn.lock, and package-lock.json for the six exact package names: @tanstack/react-router, @tanstack/history, @tanstack/router-core, @mistralai/mistralai, @mistralai/mistralai-azure, @mistralai/mistralai-gcp.
  • Grep every requirements.txt, poetry.lock, Pipfile.lock, and pyproject.toml for mistralai at version 2.4.6 and any newer version published after May 11, 2026, until the registry confirms the malicious release has been yanked.
  • Run npm audit and pip-audit across the full dependency tree, including dev dependencies. Audit tools may not flag these specific versions yet, so treat the output as a secondary check.
  • Search CI and build logs for any outbound connection to 83.142.209.194 between May 11 and the present.
  • Check production servers and developer workstations for /tmp/transformers.pyz, pgmonitor.py, and pgsql-monitor.service.

If you find any of the above on a host that runs builds or holds secrets, treat the host as fully compromised. Reimage, do not clean.

What to Rotate and Where to Revoke

The credential sweep is the single highest-leverage action. The payload targeted secrets that grant publish rights and cloud access, not just application credentials. Rotate in this priority order.

  • GitHub personal access tokens and fine-grained tokens for every developer or CI runner that shared a host with the infected packages.
  • npm publishing tokens for any account that has published or maintained the affected packages or any package in the same workspace.
  • Cloud provider API keys and service account credentials accessible from affected build environments.
  • SSH keys that lived on affected hosts, including keys baked into CI runners.
  • Any CI/CD secrets referenced by pipelines that ran on those hosts, including container registry credentials and signing keys.

Rotation only helps if the new credentials are never exposed to the same compromised surface. Move secrets into a managed vault that the build pipeline pulls at runtime, not environment variables that persist on developer laptops.

Why Official-Name Compromise Defeats Most Defenses

Most dependency security tooling ranks risk by download count, maintainer reputation, and age. Every one of those signals pointed in the safe direction for the packages hit in this campaign. That is the lesson worth internalizing: an attacker who seizes a maintainer account inherits the maintainer’s trust score. The registry sees a legitimate upload from a known publisher, and every downstream consumer sees a familiar package name on a familiar version line.

Sonatype’s 2025 State of the Software Supply Chain report put malicious open-source package uploads at roughly 200% year-over-year growth. The Mini Shai-Hulud campaign is consistent with that trend and shows it now reaching AI SDKs and frontend frameworks, the two ecosystems that ship code straight into production through automated publishing.

Structural Defenses Worth Putting in Place

Short-term cleanup matters, but the campaign also points to a set of structural controls worth adopting before the next incident.

  • Pin every dependency by exact version with an integrity hash, and treat lockfile drift as a security event, not a convenience.
  • Scope CI tokens to the narrowest permissions and shortest lifetimes the pipeline actually needs. Publishing rights should never live on the same token that runs tests.
  • Enable two-factor authentication on every package-manager account, including npm and PyPI, and prefer registry-supported trusted publishing over long-lived tokens.
  • Require signed commits and signed packages for any internal distribution channel that mirrors public packages.
  • Segment build environments so a compromised package cannot reach production secrets, cloud credentials, and the rest of the pipeline in a single hop.

FAQ

Which exact packages should I flag in my lockfiles?

Six npm packages and one PyPI package. The npm names are @tanstack/react-router, @tanstack/history, @tanstack/router-core, @mistralai/mistralai, @mistralai/mistralai-azure, and @mistralai/mistralai-gcp. The PyPI name is mistralai at version 2.4.6.

What are the file and network artifacts I should hunt for?

Look for /tmp/transformers.pyz, pgmonitor.py, and pgsql-monitor.service on Linux hosts that may have imported or installed the affected packages. Also search logs for outbound traffic to 83.142.209.194 during the May 11 to May 12, 2026 window and after.

If I find the payload file on a build runner, what is the right next step?

Treat the host as fully compromised. Reimage it, rotate every secret that host could reach, and audit any artifact that pipeline produced after the install. Cleaning the filesystem is not sufficient because the credential theft has already happened.

Related coverage