A Rust Supply-Chain Attack: the Poisoned arrayref 0.3.10 and the proc-macro1 Typosquat
Translated by a model; the original is in Russian.
On the morning of August 20, 2026, a supply-chain attack hit the Rust ecosystem, affecting one of its most widely used crates. A compromised version of arrayref, 0.3.10, quietly added a dependency on proc-macro1 1.0.107 — a typosquat of the ubiquitous proc-macro2. That package's build script downloaded a binary from a remote server and ran it on any machine that built the project. Because the malicious code lived in build.rs, simply compiling the project was enough to be infected — you didn't need to call anything from the crate at all.
How the attack unfolded
The groundwork was laid the same day. Overnight, the account dtolney was created, impersonating David Tolnay (dtolnay), the author of the real proc-macro2. First, under the squatted name, a clean copy of proc-macro2 was published — purely for the sake of plausibility. Then came version 1.0.107 with suspicious build dependencies (base64, rustls, ureq) that an honest macro library would have no need for.
At 07:15 UTC, arrayref 0.3.10 was released from the owner account droundy — the crate's first real dependency in its ten-year history. In the same minute, a script yanked versions 0.3.5 through 0.3.9 at intervals of about four seconds, so that Cargo's “yanked version” warning would nudge users into updating straight into the trap. The window of vulnerability lasted roughly 86 minutes: around 08:03 crates.io removed proc-macro1, and by 08:41 it had also pulled arrayref 0.3.10 from the index.
How the malware worked
The build.rs script assembled the infrastructure addresses from base64 fragments, downloaded a second-stage payload over TLS with certificate verification deliberately disabled, dropped it into /tmp/rust-setup on Unix (or into %TEMP% via a hidden wscript.exe on Windows), and launched it as a separate process, carefully breaking out of Cargo's job object so that the build would finish as if nothing had happened. Meanwhile, the library's own code remained the genuine proc-macro2, and the infection left no trace in the output.
The scope
arrayref has around 245 million downloads all-time. It underpins a host of Rust GUI applications (egui/eframe, iced, winit), and it also finds its way into the dependencies of blake3, revm-precompile for Ethereum, and solana-runtime/spl-token for Solana. Any CI job or developer build that re-resolved arrayref ^0.3 during those 86 minutes ran the payload with the current user's privileges.
What to do
Check your Cargo.lock: the presence of version 0.3.10 or any proc-macro1 entry means the code ran. Look for the artifacts /tmp/rust-setup, %TEMP%\rust-setup.ps1, and network traffic to 23.254.165.112. If you find any traces, treat the host as compromised and rotate every secret, token, and key accessible from it. If there are no traces, pin arrayref = "=0.3.9" and don't resolve the yank warnings by blindly updating.
Source: Lobsters
Comments
Sign in, to comment.