Rust Crate arrayref Hijacked to Run Malware at Build Time

On August 20, 2026, the arrayref crate, a Rust library with nearly 245 million downloads, published version 0.3.10 from a hijacked maintainer account. That release pulled in a malicious dependency whose build script downloads and runs a remote binary the moment you type cargo build.
The incident was reported through RustSec advisory #3161, and crates.io removed the malicious versions the same day. But it exposes a trust gap few people think about: in the Rust ecosystem, compiling a dependency means running its code, even if you never call it.
What happened
The droundy account, maintainer of arrayref, internment, and append-only-vec, was compromised. The attacker published arrayref 0.3.10 with a single change in its manifest: a new dependency on proc-macro1 version 1.0.107. It was the first dependency in the near-decade history of a crate that consisted of just four macros, with no dependencies and no build script.
proc-macro1 is a typosquat aimed at proc-macro2, the foundational crate almost every Rust macro depends on. Its source is a genuine copy of proc-macro2 with a mechanical find-and-replace rename, so builds kept working and nothing looked suspicious. The metadata forges authors = ["David Tolnay"] and points at a non-existent dtolnay/proc-macro1 repository, impersonating David Tolnay, the real maintainer of proc-macro2 under the account dtolnay.
How the payload runs
The malware lives entirely in the build.rs of proc-macro1 1.0.107. That build script:
- Stores the command-and-control address as base64 fragments, reassembling them at build time into
23.254.165.112:9089(payload host) and23.254.165.112:443(C2). - Downloads an architecture-specific binary over a TLS connection that accepts any certificate, meaning zero validation.
- Runs the binary detached from the build: on Unix it drops and executes
/tmp/rust-setup; on Windows it writes a PowerShell script and a VBScript launcher into%TEMP%and starts them hidden.
The crux is how Cargo works: it builds every declared dependency whether or not your code uses it. A single [dependencies.proc-macro1] line is enough to run the build script. You don't need to run the application, just compiling it triggers the payload.
How victims were steered into the trap
The attacker yanked the older releases 0.3.5 through 0.3.9. When a version is yanked, Cargo prints a "consider updating to a version that is not yanked" warning, quietly nudging developers toward the only non-yanked release left, which was the malicious 0.3.10. The RustSec reporter confirmed this is exactly how they got hit.
Blast radius
arrayref isn't large in code, but it sits deep in the dependency graph: through tiny-skia, sctk-adwaita, and winit, it shows up in most Rust GUI applications built on egui, eframe, and iced. The crate has roughly 245 million all-time downloads (244,989,384 at the time of writing), with the clean 0.3.9 release accounting for about 152 million.
All affected crates have since been removed by crates.io:
| Crate | Version | Status |
|---|---|---|
| arrayref | 0.3.10 | Malicious, removed |
| internment | 0.8.7 | Malicious, removed |
| append-only-vec | 0.1.9 | Malicious, removed |
| proc-macro1 | all versions | Typosquat, entire crate removed |
| proc-macro-en, aovine, arone, aronenao, tinymember | all versions | Malicious dependency crates, removed |
On attribution, Wiz reports significant overlap between this attack and previous campaigns linked to North Korean (DPRK) actors. That's a security vendor's assessment rather than an official conclusion, but it suggests this wasn't an amateur.
Why developers should care
This is a supply-chain attack, but not the familiar kind. Supply-chain attacks used to mean "break into a repository and edit the code." This one shows an attacker doesn't need to touch the source at all, just hijacking a maintainer account is enough to distribute malware.
Three assumptions the ecosystem takes for granted are now failing:
- "Maintainer account = trusted." Wrong, accounts get compromised, and a hijacked long-time maintainer is more dangerous than a suspicious new crate because the reputation is already there.
- "Popular dependency = safe." Wrong, popularity is exactly what made
arrayrefa target, since one distribution reaches millions of builds. - "Build = harmless." Wrong, build scripts run code on both developer machines and CI runners, with the full privileges of whoever is compiling.
The second-order effect worth noting: when a crate deep in the dependency graph is attacked, tracing "who got hit" is nearly impossible for any individual project. Audit tools only help once an advisory is published, and advisories always come after the fact.
What to do now
- Run
cargo audit(orcargo deny) and refresh the RustSec advisory DB to catcharrayref0.3.10 if it's still in your lockfile. - Check whether
proc-macro1orarrayref0.3.10 appears in your tree:cargo tree -i arrayref. - Review dependency
build.rsfiles like production code, that's where the payload hid this time. - Sandbox the build step in CI, and consider vendoring critical dependencies instead of downloading them at build time.
- Watch for odd metadata: near-miss maintainer names (
dtolneyvsdtolnay), repositories returning 404, and sudden new dependencies in long-stable crates.
The trust model, not the technique
The arrayref incident isn't the first and certainly won't be the last. What's worrying isn't the technique, base64-hidden C2 addresses and certificate-skipping downloads are nothing new. What's worrying is that an entire ecosystem's trust model is being systematically exploited: maintainer accounts get hijacked, reputation becomes a weapon, and the once-harmless compile step turns into a backdoor. The way the ecosystem places trust in people has to change before the next one lands.
Content assisted by AI (Amy ๐ธ). Reviewed by the author.
Related Posts
Ghosts on GitHub: 10,000 Fake Repos Spreading Trojans Target Devs
An independent developer discovered a massive, automated malware campaign using 10,000 cloned GitHub repositories to bypass security filters and target AI agents.
Miasma Worm: When AI Coding Agents Become the Trigger for Malware
The Miasma supply chain attack compromised 73 Microsoft GitHub repos, weaponizing the setup hooks of Claude Code and Cursor to silently harvest developer credentials.
Rust Glancer: A Rust LSP That Runs Under 100MB of RAM
rust-analyzer can eat gigabytes of RAM. Rust Glancer flips the architecture โ index once, store to disk, idle under 100MB.