CRITICALSecurity · Supply-chain · PyPI · Python / ML developer environments · May 2026 mistralai 2.4.6 (Linux)

mistralai PyPI 2.4.6 Compromise: Credential Stealer with Geofenced rm -rf Branch, Pin Below 2.4.6 and Triage Linux Hosts

By NewMaxx /May 12, 2026

Microsoft Threat Intelligence disclosed that version 2.4.6 of the mistralai Python package on PyPI has been compromised. According to the disclosure, attackers injected code into mistralai/client/__init__.py that executes on import, downloads a second-stage payload from hxxps://83[.]142[.]209[.]194/transformers.pyz to /tmp/transformers.pyz, and runs it on Linux. The second-stage filename deliberately mimics the Hugging Face Transformers library to blend into ML and developer environments. The main payload is a credential stealer, but it also carries a geofenced destructive branch with a 1-in-6 chance of executing rm -rf / when the system appears to be in Israel or Iran; the malware separately avoids executing in Russian-language environments. PyPI's cached listing shows the legitimate 2.x line ending at 2.0.1 (March 12, 2026); a jump to 2.4.6 is itself an anomaly, consistent with quarantine. Cap the version at mistralai < 2.4.6 (or pin exactly to 2.0.1) in every environment that may have pulled the package since the malicious release, hunt for the IOCs on Linux hosts, and rotate any credentials reachable from those hosts.

Sourcing, in three buckets. Confirmed by PyPI: the cached PyPI version history for the legitimate mistralai project shows a 2.x release line ending at 2.0.1 on March 12, 2026, with no 2.4.x releases visible. A version jump from 2.0.1 directly to 2.4.6 (skipping 2.1, 2.2, 2.3, and 2.4.0 through 2.4.5) is itself anomalous; legitimate Mistral releases would not version-jump this way. The non-visibility of 2.4.6 in the cached listing is consistent with PyPI quarantine action but is not by itself confirmation, the bulletin will be updated when PyPI's project status page or its JSON API is reachable to confirm quarantine, list the 2.4.6 sdist and wheel hashes, and document any project-page banner PyPI has added. Reported by Microsoft Threat Intelligence: the injection point in mistralai/client/__init__.py, the second-stage URL and drop path, the Linux execution profile, the persistence filenames, the credential-stealer payload, the Russian-environment exclusion, and the Israel/Iran 1-in-6 destructive branch. Not yet independently verified by this bulletin: SHA-256 hashes for the 2.4.6 wheel and sdist; SHA-256 for the dropped second-stage and persistence artifacts; whether any earlier or later version is also malicious; how the package or maintainer pipeline was compromised; current CISA KEV status. A Microsoft Defender Experts or Security Blog writeup is expected and will shift items from the third bucket into the second.

Scope: the documented second-stage and destructive branch are Linux-only. Developers on Windows or macOS who installed 2.4.6 should still treat any Python process that ran import mistralai as having executed attacker-controlled code, but should not assume the credential stealer ran (no Linux-specific drops would have executed) without evidence of the second-stage retrieving successfully.

If you only do one thing

Cap the version at mistralai < 2.4.6 (or pin exactly to the last known-good release, 2.0.1) across every environment, block egress to 83.142.209.194, hunt /tmp/transformers.pyz and pgsql-monitor.service on every Linux host that could have run import mistralai since 2.4.6 was published, and rotate the credentials those hosts had access to. If any host geolocates to Israel or Iran, verify filesystem integrity before reusing it.

Why this is a drop-everything bulletin

Three reasons this gets CRITICAL framing rather than HIGH. First, execution on import: any process that runs import mistralai or from mistralai import ... triggers the dropper, so simply listing 2.4.6 in a requirements.txt and running tests, a notebook, or a deploy step is enough to compromise the host. Second, the package name is the official Mistral AI client, not a typosquat; Python and ML developers who explicitly want the Mistral client install mistralai by name, so the affected population is exactly the audience that runs untrusted model code on well-credentialed dev workstations and CI runners. Third, the destructive branch is non-deterministic: even operators outside the geofenced regions cannot rely on conditional logic to predict who got wiped; if the geofence is loose or the IP geolocation flips, the 1-in-6 dice roll fires.

Indicators of Compromise
Compromised package: mistralai == 2.4.6 (PyPI) Injection point inside the wheel: mistralai/client/__init__.py (executes on import) Second-stage download (defanged): hxxps://83[.]142[.]209[.]194/transformers.pyz Second-stage drop path: /tmp/transformers.pyz Persistence and host-resident artifacts (Linux): pgmonitor.py pgsql-monitor.service (systemd unit; masquerades as PostgreSQL monitoring) Network IOC to block: 83.142.209.194 (egress block at perimeter and host) Destructive-branch trigger conditions (per disclosure): - System appears to be located in Israel or Iran - 1-in-6 probability per execution - Command executed: rm -rf / Negative-control behavior: - Avoids execution in Russian-language environments
IOCs as listed in Microsoft Threat Intelligence's disclosure. The transformers.pyz naming is intentional camouflage, the legitimate Hugging Face Transformers library is distributed as the transformers wheel and is never written to /tmp in normal use, so any file at /tmp/transformers.pyz should be treated as a hit. The pgsql-monitor.service unit and pgmonitor.py are believed to be the persistence layer for the credential stealer; the bulletin will be updated with SHA-256 hashes for these artifacts once a primary writeup publishes them.

Action priority by environment

Priority Environment Action
Drop-everything Linux CI runners, dev workstations, ML training boxes that ran import mistralai against 2.4.6 Isolate, hunt for IOCs, treat as compromised on any positive IOC hit, rotate every secret the process had access to regardless. If the machine is in (or geolocates to) Israel or Iran, also verify filesystem integrity before reusing the host.
Drop-everything Linux containers / images built since 2.4.6 was published Container images that resolved mistralai without a pinned ceiling during build (or pinned to 2.4.6 specifically) are exposed to malicious code. Treat as compromised only after confirming execution via build / runtime logs (import-time output, dropped artifacts on the build host, egress to the C2). Rebuild from a pinned mistralai < 2.4.6 regardless, rotate any baked-in credentials, and redeploy.
Drop-everything Internet-egress from any host that ran 2.4.6 Block 83.142.209.194 outbound at perimeter and at host firewall. Search egress logs retroactively for any connection to that IP from any source; the connection alone is sufficient evidence the dropper executed.
Same-day Windows / macOS dev hosts that installed 2.4.6 The dropper code in __init__.py would have executed in the Python interpreter on import, but the documented second-stage and credential stealer are Linux-only. Treat as exposed, not as confirmed-compromised: uninstall and pin below 2.4.6; check for any suspicious child processes, files in temp directories, or outbound connections to the C2 IP from the import window; rotate credentials only if those checks turn up evidence of execution beyond the Python interpreter, or per local policy.
Same-day Pip mirrors / internal package proxies (devpi, Artifactory, Nexus) Verify that mistralai 2.4.6 is not pinned, cached, or required by any internal build manifest. Add a deny entry for the exact version while the incident is open.
This week Environments that never installed mistralai at any version No direct action. Note the broader pattern: official-package supply-chain compromise of an AI/ML SDK with destructive payload semantics, the next one will not be on the same package or registry.

Priority assignment reflects this bulletin's framing, not an external CVSS score. PyPI supply-chain compromises do not receive CVSS in the normal vendor sense.

Am I affected?

Check pip and poetry environments

On each Linux host, virtualenv, container, and CI runner that may have installed the Mistral client, check the resolved version:

pip show mistralai 2>/dev/null | grep -E '^(Name|Version|Location):'
# or, across all environments visible to pip:
pip list --format=freeze 2>/dev/null | grep -i '^mistralai=='

For Poetry projects, check the lockfile rather than the live environment, because a fresh resolution from pyproject.toml can mask a previously-locked malicious version:

grep -A1 '^name = "mistralai"' poetry.lock | head -4
# or, for any project using pip-compile / pip-tools:
grep -i '^mistralai==' requirements*.txt

Hunt for the second-stage and persistence on Linux

Even if pip no longer shows 2.4.6, the dropper may have executed at least once. Look for the dropped second-stage and the persistence unit:

ls -la /tmp/transformers.pyz 2>/dev/null
find / -xdev -name 'transformers.pyz' 2>/dev/null
find / -xdev -name 'pgmonitor.py'    2>/dev/null
systemctl list-unit-files | grep -i 'pgsql-monitor'
systemctl status pgsql-monitor.service 2>/dev/null
# review recent shell history and journal for the IP
grep -r '83\.142\.209\.194' /var/log /root/.bash_history /home/*/.bash_history 2>/dev/null
journalctl --since '30 days ago' | grep -E '83\.142\.209\.194|transformers\.pyz|pgsql-monitor'

Verify outbound egress to the C2

The single most reliable indicator that the dropper executed on a host is an outbound connection to 83.142.209.194. Query whatever flow / DNS / proxy telemetry you have:

conntrack -L 2>/dev/null | grep '83\.142\.209\.194'
# zeek conn.log, suricata eve.json, palo alto / fortigate flow exports, etc.
# any source IP that connected to 83.142.209.194 in the affected window
# should be treated as a confirmed dropper execution.

Response steps

  1. Cap the version and unstick locked environments. For urgent operator response, pin exactly to the last known-good release: pip install 'mistralai==2.0.1'. As a policy ceiling that survives a clean 2.4.7 release, use mistralai < 2.4.6 or mistralai != 2.4.6 in requirements.txt, pyproject.toml, and any Poetry / pip-tools constraint files. Rebuild lockfiles from clean. If 2.4.6 is currently installed in a venv, run pip uninstall -y mistralai && pip install 'mistralai==2.0.1'. Do not assume a downgrade in place cleans the host; treat downgrade as remediation only for the package, not for the host. why: stops further dropper executions on import; necessary but not sufficient
  2. Block the C2 IP at the perimeter and on hosts. Add 83.142.209.194 as a deny in firewall, egress proxy, and host iptables / nftables rules. Block before, not after, you start the host-triage step, so any retry attempts during triage cannot succeed. why: severs the second-stage download path and the credential exfil channel
  3. Isolate any Linux host with a positive IOC hit. A confirmed hit is any of: /tmp/transformers.pyz present, pgsql-monitor.service registered, pgmonitor.py on disk, or an outbound flow to 83.142.209.194 in retained logs. Pull the host off production network paths before continuing. Snapshot state for forensics if your environment supports it. why: the credential stealer continues exfiltrating until persistence is removed; isolation buys triage time
  4. Rotate every credential reachable from an affected host. Cloud provider API keys and IAM session tokens in process env or instance metadata; Hugging Face tokens; OpenAI / Anthropic / Mistral API keys; npm / PyPI / GitHub tokens; SSH private keys and any authorized_keys agent-forwarded into the host; database passwords in .env, .netrc, or shell history; browser-resident session cookies on dev workstations. Assume the credential stealer had read access to everything the Python process and the user could read. why: credential theft is the documented main payload; rotation is the only reliable remediation
  5. Remove persistence and the second-stage. On each affected Linux host, after isolation, disable and remove the systemd unit and delete the dropped files:
    systemctl stop pgsql-monitor.service 2>/dev/null
    systemctl disable pgsql-monitor.service 2>/dev/null
    rm -f /etc/systemd/system/pgsql-monitor.service \
          /usr/lib/systemd/system/pgsql-monitor.service \
          /tmp/transformers.pyz
    find / -xdev -name 'pgmonitor.py' -delete 2>/dev/null
    systemctl daemon-reload
    For hosts geolocating to Israel or Iran specifically, before treating the host as recoverable, verify filesystem integrity (root directory still populated, package manager database intact, critical services present). The rm -rf / branch may have fired and partially completed before the OS aborted it. why: dropper-installed persistence survives a pip uninstall; the destructive branch leaves recoverable but inconsistent state
  6. Rebuild rather than clean where feasible. For ephemeral CI runners, container images, and disposable dev VMs, destroy and rebuild from a known-good base. For long-lived workstations, weigh the cost of reimaging against the difficulty of being confident every persistence path is gone, the credential stealer's persistence beyond the systemd unit is not fully enumerated in the initial disclosure. why: supply-chain implants frequently have secondary persistence not documented in the first writeup
  7. Search retroactively for evidence of dropper execution before any of the above ran. Look back as far as your egress and DNS logs allow for connections to 83.142.209.194 from any source. Each unique source IP is a host to add to the isolation list. If you have CI build logs, search them for mistralai-2.4.6 install lines. why: the affected population is everyone who ran import, not just everyone who still has 2.4.6 installed today
  8. Add a deny rule for mistralai 2.4.6 in your internal package proxy. If you run devpi, Artifactory, Nexus, or a similar pull-through proxy, configure an explicit deny for mistralai==2.4.6 and any version that PyPI later marks malicious. This prevents reinstallation when a developer's local pip cache or a stale lockfile attempts to re-pull during the incident window. why: lockfile-pinned environments may keep trying to install the malicious version until the proxy refuses to serve it

The broader pattern: this is the fifth named-package supply-chain compromise this project has tracked in 2026 (Lightning, xinference, Bitwarden CLI, Checkmarx KICS, and now mistralai), and the second where the malicious payload targets ML / AI developer environments specifically. The chosen camouflage filename (transformers.pyz, mimicking Hugging Face Transformers) is a signal that attackers are building per-ecosystem tradecraft for AI/ML toolchains rather than treating them as generic Python installations. Operators in this audience should expect more of the same: official-name packages, on-import execution, AI-themed second-stage filenames, and credential exfil tuned to API-key-rich developer hosts.

Caveats and unknowns

Bucket reminder: items confirmed by PyPI are in the framing block at the top; items reported by Microsoft Threat Intelligence are in the lede, callout, and IOC block; items not yet independently verified are listed here. Pending primary-source confirmation: SHA-256 hashes for the 2.4.6 wheel and sdist (PyPI assigns these to every distribution and will list them on the project's JSON API once project-page status is reachable); SHA-256 for the dropped second-stage transformers.pyz and the persistence artifacts pgmonitor.py and pgsql-monitor.service; whether any version other than 2.4.6 was malicious; the entry point for the compromise (maintainer-account takeover, build-pipeline compromise, or other); current CISA KEV status. The bulletin will be updated when the Microsoft Defender Experts or Security Blog writeup publishes, and when PyPI's project page or JSON API is reachable to confirm quarantine and list hashes.

Time-relative note: "still active" claims and "expected writeup" are anchored to May 12, 2026. If you are reading this materially later, check the primary source and PyPI's project page for current status before acting on the priority table as written.