News

Poisoned arrayref, internment and append-only-vec crates ran a compile-time payload through a typosquat build script

The Rust Security Response WG and RUSTSEC-2026-0260 detail how a republished arrayref 0.3.10 pulled in typosquat dependency proc-macro1, whose build.rs fetched and ran malware at compile time. The bad arrayref was downloaded 2,285 times, not the 244M lifetime figure some headlines used.

Poisoned arrayref, internment and append-only-vec crates ran a compile-time payload through a typosquat build script

The Rust Security Response WG, in an advisory Manish Goregaokar published on August 20, and RUSTSEC-2026-0260 describe a supply-chain attack on three popular crates. A republished arrayref 0.3.10 gained a new direct dependency on proc-macro1, a typosquat of the real proc-macro2, and that dependency's build.rs downloaded and executed a payload at compile time. The same pattern hit internment 0.8.7 and append-only-vec 0.1.9. The Rust blog credits the Research Team at Nextron Systems GmbH with reporting it at 07:15 UTC, and Wiz, Socket and BleepingComputer followed. The instrument is a compile-time build script inside a fake dependency, not a proc-macro that runs when you call it.

The instrument: a build.rs payload, not a macro that runs at use

The distinction matters for who is exposed. A proc-macro executes when downstream code invokes it. A build.rs runs automatically during cargo build, before any of your code runs, so simply compiling a project that resolved the bad release is enough. Socket puts it plainly: the crate "automatically executes its build.rs during compilation" with no explicit function call required. Wiz adds the detail that makes the arrayref case stand out: proc-macro1 "was the first dependency added to arrayref in its ten-year history," a red flag on a crate that had shipped dependency-free for a decade.

The Rust team's read is that this is a hijack, not a rogue maintainer. The advisory says "we do not believe the author of arrayref to be acting maliciously, but their computer or credentials are likely compromised," and the maintainer account droundy was locked as a precaution. The fake proc-macro1 was published under the account dtolney, and the team deleted a cluster of related typosquats: proc-macro1, proc-macro-en, aovine, arone, aronenao and tinymember.

The number under the headline: 2,285 downloads, not 244M

Here is the figure the "244 million downloads compromised" headlines get wrong. RUSTSEC states the malicious arrayref "was downloaded 2,285 times, which constituted less than 10% of arrayref download traffic across all versions." The 244M number is lifetime download volume across every arrayref release ever, not the poisoned one; most lockfiles stayed pinned to older, clean versions and never resolved 0.3.10. The blast radius is the set of hosts that actually built the bad release, and that set is small.

The exposure windows were short by design. Per the advisory, arrayref 0.3.10 was online 86 minutes (07:15:00Z to 08:41:40Z), internment 0.8.7 about 90 minutes (07:34:07Z to 09:04:11Z) and append-only-vec 0.1.9 about 107 minutes (07:37:49Z to 09:25:24Z). The gap between reach and exposure is the whole story: Wiz notes arrayref sits in over 35% of all environments and about three-quarters of environments where Rust is present, yet only a couple thousand downloads of the malicious version went out before it was pulled.

The DPRK overlap that is not attribution

Wiz reports that the arrayref "infrastructure substantially overlaps with operations attributed to recent North Korean actors." The payload beacons to the path /49890878, which Wiz says has been used in the Mastra campaign that Microsoft attributes to DPRK-linked Sapphire Sleet, the C2 IP shares an SSL issuer with that campaign's infrastructure, and a related IP appears in Google and Mandiant analysis tying UNC1069 to North Korea. Both operations lean on the same Hostwinds address range. That is overlap, and Wiz frames it as attributed activity rather than its own confirmed finding, so the attribution should be read as strongly suggestive, not closed. The concrete indicators to hunt are firmer than the flag on the actor: the C2 lives at 23.254.165.112 on ports 9089 and 443, with traffic encrypted using AES-128-GCM under the hardcoded key "i am botking."

What the implant does, and the claim Wiz walked back

Precision on impact matters here, because Wiz corrected itself. An earlier version of the writeup said browser credentials were stolen; the correction reads: "A prior version of this piece mistakenly stated that browser credentials were stolen. The queries only enumerate saved logins, they do not retrieve the encrypted credential material." So the implant inventories which logins are saved rather than exfiltrating the encrypted secrets themselves. That narrows what "infostealer" means in this case, but it does not narrow the response: any machine that ran cargo build against an affected version executed attacker code before the correction ever mattered, so it should be treated as compromised regardless of what the implant chose to read.

The takeaway

Treat any host that built arrayref 0.3.10, internment 0.8.7 or append-only-vec 0.1.9 as compromised: rotate credentials, rebuild from a clean system, and hunt for connections to 23.254.165.112 on ports 9089 and 443. Pin your lockfiles to the safe releases, arrayref 0.3.9 or earlier, internment 0.8.6 or earlier, append-only-vec 0.1.8 or earlier, since there is no patched version to upgrade to. And do not size the incident off the 244M lifetime-download figure. The number that defines exposure is 2,285, and the question that defines yours is whether a build ever resolved one of those releases.

Cyberpresso: daily cyber & AI brief

Free daily newsletter, read in 5 minutes.

Subscribe free