Short version: a compromised maintainer pushed malicious releases to a handful of Rust crates that quietly pulled in a tiny, typo-named dependency whose build script grabbed and ran a payload during compilation. The bad versions were pulled down within a couple of hours, but the incident still left a big footprint — including an affected crate with roughly 245M downloads.
What happened (in plain, slightly panicked English)
Someone got into an owner account and released new versions of three crates: arrayref, internment, and append-only-vec. Each of those new releases added a dependency on a maliciously named crate (a typosquat of proc-macro2 called proc-macro1) that looked and built like the real thing — except its build script reconstructed a remote host address, disabled TLS checks, downloaded a platform-specific payload, and launched it right in the middle of a normal build.
That means you didn’t have to call any function or import any symbol from the infected crates — just running cargo build, cargo check, or cargo test could be enough to execute the payload. The attacker also attempted to make the malicious release the only un-yanked version so Cargo’s usual update warning would nudge people toward it.
- Affected crates: [email protected], [email protected], [email protected] (published the same day and removed shortly after).
- Up-time of malicious releases: roughly 86, 90, and 107 minutes respectively before removal.
- Technique: dependency typosquat + build-time execution (not a runtime library call).
- Evidence so far: maintainers removed the bad versions fast; no confirmed widespread exploitation has been reported yet.
The malicious build script did several nasty little tricks: reassembled a C2 host from base64 fragments, installed a certificate verifier that accepted anything (bye-bye TLS verification), chose a payload for your OS/CPU, wrote an executable (or a PowerShell script on Windows), and spawned it detached so the build process wouldn’t wait around. On Linux/macOS it wrote to /tmp/rust-setup; on Windows it used a hidden VBScript launcher and a PowerShell drop in %TEMP%.
How to check yourself and limit the damage
Keep calm, but do a few detective moves. If you build Rust code on your machine, check these things right now:
- Search your local cache for removed package files:
~/.cargo/registry/cache. Remove any suspicious or recently downloaded archives you don’t recognize. - Pin arrayref to a safe version: require
0.3.9or earlier if you depend on it indirectly. - Scan for the common dropped files and artifacts:
/tmp/rust-setup,%TEMP%\rust-setup.ps1, and%TEMP%\rust-setup-launch.vbs. - Check running processes and autorun entries for persistence: look for Registry Run keys on Windows, LaunchAgents on macOS, and systemd user services on Linux.
- Revoke and rotate credentials if you suspect a compromise; the incident involved forged author metadata and an apparent account compromise.
Indicators observed in the wild include an IP host and C2 ports, specific temporary filenames, and several bogus crate account names. If you manage CI systems or build servers, make sure you’re not auto-building unreviewed, brand-new crate versions — the safest route is to pin dependencies and add extra scrutiny for fresh publishes.
Final notes: there’s no neat patched version to upgrade to in this case, and a formal CVE wasn’t attached at the time of write-up. The attack relied on the build phase, which is why supply-chain defenses that only look at runtime behavior can miss it. Consider tightening publish and consumption policies and adopting a cooldown or review step for newly published third-party packages.
And yes: next time your build acts weird, before blaming Cargo, maybe blame the gremlin that sneaked into a maintainer account.