Skip to content
supplychainattack.orgSupply chain attack incident catalog

mrmustard PyPI Package Compromise Steals Cloud Credentials

Trojanized mrmustard 0.7.4 on PyPI stole SSH keys, cloud credentials and Kubernetes config from developers. How to check if you are affected.

Published 7 min read
pypipythonmalwarecredential-theftkubernetessupply-chain

A malicious release of mrmustard, version 0.7.4, reached PyPI this week and was caught stealing developer credentials. The package name belongs to a real project. MrMustard is Xanadu's open-source Python library for simulating photonic quantum computers, so the poisoned build landed inside a namespace that scientific and machine learning teams already trust. Researchers at StepSecurity and safedep both flagged the 0.7.4 release as a credential stealer that targets SSH keys, cloud provider credentials, and Kubernetes configuration. We recorded it on 2026-07-24 as a critical PyPI package compromise. If you run quantum or scientific Python in CI, this one is worth ten minutes of your attention.

What happened

Someone published version 0.7.4 of mrmustard to PyPI under the legitimate project name. That distinction matters. This was not a typosquat sitting next to the real package with a slightly altered name. It was a poisoned release inside the real project's namespace, which means a normal pip install mrmustard or an unpinned upgrade would pull the trojanized version.

StepSecurity published its analysis under the title "Compromised PyPI Package: mrmustard 0.7.4 Steals SSH, Cloud, and Kubernetes Credentials." The team at safedep described the same release as trojanized to steal credentials. Both point to one behavior: the package carries code that collects secrets from the machine that installs it and sends them to an attacker.

Because the malicious code shipped inside the genuine package name, the most likely explanations are a compromised maintainer account or a stolen PyPI publishing token. As of this writing the exact initial-access path has not been confirmed publicly, and neither has the precise moment the release went live. Treat the version number, 0.7.4, as the reliable indicator of compromise rather than any single network artifact.

Timeline

  • 2026-07-24: The compromised mrmustard 0.7.4 release is documented by StepSecurity and safedep and recorded in our catalog as critical.
  • Exact PyPI publish time: not stated in the public write-ups we reviewed. If you keep install logs, check when 0.7.4 first appeared in your environments instead of anchoring on a single disclosure date.

This is a narrow, well-scoped incident, not a self-replicating worm. It sits alongside a busy week for registry attacks. The same period brought a run of malicious npm packages, including entries such as fs-extra-core and svgcraft-core. The common thread across all of them is the same goal: read local secrets from developer and CI machines and exfiltrate them.

Who is affected

Anyone who installed mrmustard 0.7.4 from PyPI is in scope. In practice that means quantum computing researchers, photonics labs, physics and optics groups, and machine learning teams that pull the library into notebooks, experiments, or automated pipelines. It also means any CI job that resolved mrmustard without a pinned version or a hash, because CI runners are the ideal victim for this class of malware.

MrMustard is a specialized library, so the raw number of affected installs is smaller than you would see from a mainstream package compromise. Do not read that as low risk. The people who install a photonic quantum simulator tend to work on machines that hold SSH keys into research clusters, cloud credentials for GPU and simulation workloads, and kubeconfig files for shared infrastructure. Those are exactly the three credential classes the researchers named. A narrow blast radius that lands on high-value hosts is still a serious problem.

The most dangerous case is a shared CI runner or a build image that installed 0.7.4. If the runner had ambient cloud credentials, a checked-out deploy key, or a service account token mounted into the job, assume those secrets left the building the moment the package installed.

How the attack works

Python packages get two chances to run code you did not write. The first is during pip install, when the build backend executes while the package is prepared. The second is at import time, when top-level module code and __init__.py run the moment your program calls import mrmustard. Credential stealers on PyPI use one or both of these moments. The published analyses of mrmustard 0.7.4 describe the payload doing what the headline says: reading local secrets and shipping them off host.

The three credential classes named by StepSecurity map to well-known locations on a developer or CI machine:

  • SSH private keys under ~/.ssh/, for example id_rsa and id_ed25519, plus known_hosts and config, which together reveal both the keys and the hosts they open.
  • Cloud provider credentials such as ~/.aws/credentials, files under ~/.config/gcloud/, and Azure token caches, along with any cloud secrets exposed through environment variables.
  • Kubernetes configuration in ~/.kube/config, which often holds long-lived tokens or client certificates for production clusters.

Once collected, that data is exfiltrated to an attacker-controlled endpoint. We have not seen a specific command-and-control domain published in the two analyses, so do not build your response around a single network indicator. The safe assumption is simpler: any host that installed 0.7.4 had those files read, and every credential reachable from that host should be treated as exposed.

How to check whether you are affected

Start by asking whether the version is present anywhere on the machine. Run these in each environment and container image you care about.

# Is it installed in the current interpreter?
pip show mrmustard
python -c "import importlib.metadata as m; print(m.version('mrmustard'))"

# List it across the active environment
pip list 2>/dev/null | grep -i mrmustard

Then look for the exact bad version in the places that record what you installed:

# Lockfiles, requirement files, and constraints
grep -RniE "mrmustard[=~ ]*0\.7\.4" \
  requirements*.txt constraints*.txt poetry.lock Pipfile.lock pdm.lock 2>/dev/null

# pip's local cache of downloaded artifacts
grep -Rni "mrmustard-0.7.4" ~/.cache/pip 2>/dev/null

In CI, grep your pipeline logs for the resolved version. Any line that shows mrmustard-0.7.4 being downloaded or installed is a confirmed hit, even if the runner has since been torn down.

How to remediate

If 0.7.4 is present, or if you cannot rule it out on a host that installed mrmustard this week, act as though the credentials on that host are already in an attacker's hands. Removing the package is the first step, not the whole job.

# Remove the malicious version
pip uninstall -y mrmustard

# Reinstall a known-good version explicitly if you still need the library
# (verify the version against the project's official releases first)
pip install "mrmustard==<known-good-version>"

Now rotate everything the malware could have read. Order matters: revoke first, then reissue.

# SSH: generate a fresh key, deploy it, then remove the old public key
# from every authorized_keys file that trusted it
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new

# AWS: deactivate and delete the leaked access key, then create a new one
aws iam list-access-keys
aws iam update-access-key --access-key-id OLD_KEY_ID --status Inactive
aws iam create-access-key
aws iam delete-access-key --access-key-id OLD_KEY_ID

For Google Cloud and Azure, revoke the affected service account keys or refresh tokens and issue new ones. For Kubernetes, rotate the tokens and client certificates referenced in ~/.kube/config, and cycle any service account whose token was mounted into an affected job. If the host held a signing key, an API token for a package registry, or a personal access token, revoke those too.

For CI, do not clean in place. Destroy and rebuild the affected runners or build images, then re-run the job with rotated secrets. Ephemeral runners exist for exactly this reason.

Finally, make the next poisoned release harder to reach. Pin dependencies and verify hashes so a surprise version cannot slip in:

# Fail the install if any artifact hash does not match the lockfile
pip install --require-hashes -r requirements.txt

A pull-through proxy or an internal index with an allowlist gives you a second control, and it lets you quarantine a specific version the moment a report like this lands.

FAQ

Is mrmustard safe to use?

The project itself is a legitimate Xanadu library. The problem is the specific 0.7.4 release published to PyPI, which StepSecurity and safedep identified as a credential stealer. Avoid 0.7.4, pin to a version you trust, and verify it against the project's official releases before reinstalling.

How do I know if I installed the malicious mrmustard 0.7.4?

Run pip show mrmustard in each environment and grep your lockfiles and CI logs for mrmustard-0.7.4. A match anywhere, including a torn-down CI runner, counts as an exposure. Absence of the version string across environments, lockfiles, and pip cache is a reasonable all-clear.

What should I do if I ran mrmustard 0.7.4 in CI?

Assume every secret reachable from that job is compromised: cloud credentials, deploy keys, service account tokens, and registry tokens. Rotate all of them, then destroy and rebuild the runner or image rather than cleaning it in place.

Does removing the package fix the problem?

No. Uninstalling stops the code from running again, but it does not recover credentials that were already read and sent off host. The recovery work is credential rotation and rebuilding any machine that installed 0.7.4.

Sources

  1. Compromised PyPI Package: mrmustard 0.7.4 Steals SSH, Cloud, and Kubernetes Credentials · StepSecurity
  2. mrmustard PyPI Package Trojanized to Steal Credentials · safedep
  3. mrmustard project page · PyPI
  4. XanaduAI/MrMustard · Xanadu / GitHub