Open Source · · 1 day
Xanadu MrMustard PyPI release stole HPC and cloud credentials
mrmustard 0.7.4 was uploaded to PyPI on 2026-07-23 from a hijacked maintainer account with no matching tag or commit upstream. It read SSH keys, AWS credentials, and kubeconfig on import, and installed three persistence mechanisms.
A malicious release of mrmustard, the photonic quantum computing library published by Xanadu, appeared on PyPI on July 23, 2026. Anyone who ran import mrmustard from version 0.7.4 had their SSH private keys, AWS credentials, and Kubernetes configuration read off disk and sent to an attacker-controlled server.
MrMustard is a research library for simulating photonic quantum circuits, the kind of package that lives on university workstations and HPC login nodes rather than in web application pipelines. The payload was built for that audience. Alongside the usual cloud secrets it collected SLURM job queues and GPU inventories, which is a reasonable way to map a research cluster from a single infected laptop.
The mismatch between PyPI and GitHub gave the incident away. Version 0.7.4 exists on PyPI with no corresponding tag, release, or commit in the XanaduAI/MrMustard repository, whose tags stop at v0.7.3. StepSecurity and SafeDep, which both analyzed the release, traced the route in. Two commits were pushed on July 23 through the account of ziofil, the project's original author, both on throwaway branches since deleted. The first deleted seven legitimate workflow files and added one that ran whoami on the project's self-hosted runners, which is reconnaissance and nothing else. The second added a workflow that read PIPY_TOKEN and CODECOV_TOKEN out of Actions secrets, base64 encoded them, and curled them to a webhook.site collection URL. With the publishing token in hand the attacker uploaded the poisoned artifact straight to the index, skipping the repository entirely.
Execution happened at import rather than at install, so the code ran the first time a researcher used the library rather than when pip finished, and it sat out any run where CI variables or a container were detected. The collected data went to https://metrics.femboy.energy/v1/collect, a URL the payload kept XOR obfuscated under the key tf_compat_v2 rather than in plaintext. The payload then compiled a copy of itself to ~/.cache/.tf_cache/hw_probe.pyc and pointed three independent persistence hooks at it: a cron job every fifteen minutes, a line in ~/.bashrc or ~/.zshrc disguised as a # tensorflow hardware compatibility check, and an mmcompat.pth file in site-packages. The last of those is the worst of the three. Python executes .pth files on every interpreter start, so the stealer ran on any python invocation, survived pip uninstall mrmustard, and on a shared HPC login node ran for every user who started Python there. Anyone who imported the affected version was told to treat the host as compromised and rotate every credential that had been present on it.
Notes
- Version 0.7.4 has no matching tag, release or commit in XanaduAI/MrMustard, whose tags stop at v0.7.3. It was uploaded straight to PyPI after takeover of a maintainer's GitHub account and use of the project's CI to get the token.
- The payload is a 258-line _check_tf_compatibility() in mrmustard/__init__.py; the rest of 0.7.4 is byte-identical to 0.7.3. It runs at import, installs three persistence mechanisms, and skips CI and container environments.
- The C2 URL is XOR obfuscated with the key tf_compat_v2 and decodes to https://metrics.femboy.energy/v1/collect. Collected JSON is encrypted with the same key, base64 encoded, and posted with a spoofed browser User-Agent.
- PyPI hard-deleted 0.7.4 and the removal reached the simple index and its mirrors. Software Heritage visited the PyPI origin on 2026-07-24, between publish and removal, so the sdist tree survives there; the wheel does not.
Appendix · Affected releases
- Hash order is the complete malicious PyPI files mrmustard-0.7.4-py3-none-any.whl and mrmustard-0.7.4.tar.gz. OSSF's record preserves both filenames and their integrity SHA-256 values after PyPI removed the release.
- The original archive bytes remain unavailable. samples/mrmustard/during holds a tree-equivalent sdist reconstruction from Software Heritage plus report-derived import-hook, evasion and persistence excerpts.
Indicators
- filemrmustard/__init__.py
- function_check_tf_compatibility
- urlhttps://metrics.femboy.energy/v1/collect
- domainmetrics.femboy.energy
- urlhttps://webhook.site/710babde-6ace-47fe-83f4-9688e6548df9
- file~/.cache/.tf_cache/hw_probe.pyc
- path~/.cache/.tf_cache/
- filemmcompat.pth
- command*/15 * * * * /usr/bin/env python3 ~/.cache/.tf_cache/hw_probe.pyc
- marker# tensorflow hardware compatibility check
- codetf_compat_v2
- accountziofil
- commit2ebfe28
- commit80aba72
References
Source record: oss/attacks/mrmustard/meta.yaml