A poisoned Rust crate with 245 million downloads shows how a build script can compromise you before you run the program
On 20 August, attackers pushed malicious versions of three popular Rust crates, led by arrayref, which has 245 million downloads and sits under 403 other packages. The twist: the malware ran during compilation, not when the program was run. A build script pulled from a typosquatted dependency downloaded and ran an infostealer during cargo build, so merely building a project could be enough to be hit. This is a package-registry supply-chain attack, not a flaw in the Rust language, and the same trick has repeatedly hit npm and other ecosystems. Rust's security team yanked all three within about 90 minutes.

On 20 August 2026, an attacker published malicious versions of three widely used Rust crates, arrayref, internment and append-only-vec, from a compromised maintainer account. arrayref alone has about 245 million all-time downloads and 403 packages depend on it directly. Each poisoned release quietly added a dependency on proc-macro1, a typosquat of the real proc-macro2, whose build script downloaded and ran an infostealer during compilation. Because the code executed at build time (cargo build, check or test), a developer did not even have to run their program to be compromised. The malware read saved-login databases from Chromium browsers and set up persistence. Rust's Security Response Working Group caught and removed all three within roughly 86 to 107 minutes, so the popularity numbers describe the crate's reach, not the number of victims. Worth stating plainly up front: this is a supply-chain attack on the package registry and build system, not a weakness in the Rust language itself.
Most software supply-chain scares are about code that misbehaves when you run it. This one is nastier in a quiet way: the malicious code ran the moment a developer compiled their project. On 20 August 2026, the Rust ecosystem had its first high-profile crates.io compromise of this kind, and the mechanism is a useful lesson in where trust actually lives in modern software.
What happened?
According to the official Rust Security Response post, an attacker gained control of the account of a longtime crate maintainer and published malicious versions of three legitimate, popular crates:
- arrayref 0.3.10
- internment 0.8.7
- append-only-vec 0.1.9
These are not obscure packages. As The Hacker News reported, arrayref has about 245.4 million all-time downloads (roughly 53.9 million in the 90 days before the attack) and 403 crates list it as a direct dependency. A poison in a package that far down the stack can reach an enormous number of projects.
The attacker did not hide the payload inside arrayref itself. Instead, each compromised release added a single new dependency on proc-macro1, a name chosen to look like the real, ubiquitous proc-macro2 crate. That was the first dependency arrayref had taken on in its roughly ten-year history, the kind of change that is an obvious red flag in hindsight but easy to miss in the moment. The attacker also uploaded several other malicious crates (proc-macro-en, aovine, arone and aronenao), and, according to the disclosure and follow-up analysis, at least one was published under a username impersonating a prominent Rust developer, a lookalike-identity trick that makes a malicious upload look trustworthy. The reporting suggests the campaign was still expanding when it was stopped.
Why "build-time" is the scary part
Here is the detail that makes this incident worth understanding. In Rust, a crate can ship a build script (a build.rs file) that Cargo runs during compilation to do setup work. The malicious proc-macro1 used its build script to download and execute a payload. That means the bad code fired during ordinary developer commands, cargo build, cargo check and cargo test, not when the finished program was run.
The practical consequence is unsettling: you did not have to run the software to be compromised. Opening a project in an editor that checks it, compiling it once, or a continuous-integration job that builds it, was enough. Build scripts are a normal, useful feature, but they run with the developer's privileges and full network access, so a compromised one can act as remote code execution on the machine doing the build. In this incident that meant any machine that built one of the poisoned versions during the short window they were live. That is the trust boundary most people forget about: you vet the code you write and the code you ship, but the toolchain runs a lot of other people's code in between.
What the malware actually did
The payload was an information stealer. Per the reporting, the second-stage implant read saved-login databases from Chromium-based browsers, Chrome, Brave and Edge, by querying their local SQLite credential stores. It also installed persistence so it would survive a reboot, using Registry Run keys on Windows, a LaunchAgent on macOS and a systemd service on Linux, and it maintained a command-and-control channel that could terminate itself, change its C2 address, reinstall persistence or run further scripts. In short: steal credentials now, keep a foothold for later.
How bad was it, really?
This is where the big number needs context. arrayref's 245 million downloads (and even the roughly 54 million in the prior 90 days) describe how popular the crate is over its lifetime, not how many machines were infected, and neither figure measures exposure to this incident. They are why an attacker picked arrayref, not a count of victims. The malicious versions were live only briefly. The Rust team received the report at 07:15 UTC on 20 August and removed the crates fast: arrayref 0.3.10 was online for about 86 minutes, internment 0.8.7 for about 90 minutes, and append-only-vec 0.1.9 for about 107 minutes. The only machines at risk are the far smaller number that happened to pull one of the poisoned versions during those roughly 90-minute windows, for example by adding the crate fresh or running an update that resolved to the new version. A fast response almost certainly kept real infections low.
That said, "briefly live" is not "harmless." Anyone caught in the window should treat it as a genuine credential compromise: the whole point of an infostealer is that the damage outlives the malware.
What to do, and what it means
Rust's Security Response Working Group published guidance to help developers check whether a poisoned version ever landed in their local Cargo cache, and the malicious versions have been removed from crates.io so fresh builds will no longer pull them. If you build Rust projects, the sensible steps are to check your caches and lockfiles against the affected versions, and if you find one, assume saved browser credentials on that machine may have been taken and rotate them.
The broader lesson is not "Rust is unsafe", it is the opposite of comforting: this is the same supply-chain playbook that has repeatedly hit npm and other registries, and Rust's memory-safety guarantees do nothing to stop it, because the attack is on the distribution and build layer, not the language. A maintainer account is a single point of failure; a build script is code you run without reading; and a lookalike dependency name is easy to miss in a diff. The disclosure has not said exactly how the account was taken over, which matters for the remedy: if it was phished credentials, hardware-backed multifactor would raise the bar, but if it was a stolen session token, MFA alone would not have stopped it. Either way the structural fixes are the boring ones: stronger, phishing-resistant account security for maintainers, closer scrutiny of new dependencies (a first-ever dependency is an obvious flag in hindsight), and build systems that do not silently grant every build script full network and file access.
The attack at a glance
| When | 20 August 2026, report received 07:15 UTC |
| Poisoned legit crates | arrayref 0.3.10, internment 0.8.7, append-only-vec 0.1.9 |
| Delivery vehicle | proc-macro1 (typosquat of proc-macro2) + malicious decoy crates |
| How it ran | Build script (build.rs) executed during cargo build / check / test |
| Reach of arrayref | ~245.4M all-time downloads; 403 direct dependents |
| Payload | Infostealer: browser credential theft (Chrome/Brave/Edge) + cross-OS persistence + C2 |
| Time live | ~86 to 107 minutes before removal |
| Attribution | No one has been confirmed responsible |
Frequently asked questions
What is a build-time supply-chain attack?
It is malware that runs while you compile code, not when you run the finished program. In this case a Rust build script (build.rs) downloaded and executed a payload during cargo build, cargo check or cargo test. Because compiling a project was enough to trigger it, developers and CI systems could be compromised without ever running the software.
Which Rust crates were affected?
Malicious versions of three legitimate crates, arrayref 0.3.10, internment 0.8.7 and append-only-vec 0.1.9, plus a set of purely malicious crates led by proc-macro1 (a typosquat of proc-macro2). All were removed from crates.io.
Does 245 million downloads mean 245 million victims?
No. That figure is arrayref's all-time popularity, not the number of infected machines. The malicious versions were live for only about 90 minutes each, so only those who pulled a poisoned version in that window would have run the payload. The number describes exposure risk, not victims.
What should I do if I build Rust projects?
Check your local Cargo cache and lockfiles for the affected versions using the Rust team's guidance. If you find one, assume the machine's saved browser passwords may have been stolen, rotate those credentials, and rebuild from clean, current versions.
Is this a flaw in the Rust language?
No. Rust's memory-safety guarantees are about the code you write; this attack targeted the package registry and build system, the distribution layer, which every language shares. The same pattern has repeatedly hit other ecosystems such as npm.


