Supply-chain case study
Threat analysis · 21 Aug 2026cargo build.
On 20 August 2026, attackers republished arrayref — a
crate with more than 245 million
downloads — and two siblings, internment and
append-only-vec, with a malicious build script that
executed at compile time, on developer and CI machines. The
poisoned versions were live for roughly
90 minutes before crates.io
yanked them. Here is what the payload did — and, honestly, where a
registry helps and where build sandboxing is the real fix.
cargo build in that window, act first, read second.
Treat any workstation or CI runner that resolved arrayref,
internment or append-only-vec between
~14:00 and ~15:30 UTC on 20 Aug 2026 as credential-exposed. The
payload ran with your build's privileges, so rotate browser-stored
credentials, cloud tokens and SSH keys that machine could reach, and
grep your build hosts for the IOCs below.
What happened
Rust's build model trusts build.rs and procedural
macros to run arbitrary code on the build host — that is by
design, and it is what this attack abused. The poisoned releases
pulled in a companion crate, proc-macro1 (a
look-alike of the legitimate proc-macro2), whose
build step acted as a dropper: during cargo build
it wrote an executable to /tmp/rust-setup and ran
it, before a single line of the developer's own code compiled.
The dropped binary went after locally stored secrets — browser credential and cookie stores in particular — and beaconed to a hard-coded command-and-control host at 23.254.165.112, requesting the path /49890878. Because it fired at compile time, it hit exactly the machines a supply-chain attacker wants: developer laptops with live SSO sessions, and CI runners holding deployment credentials.
The blast radius was capped by speed of response, not by any
control on the consumer side: crates.io yanked the malicious
versions about 90 minutes after they appeared. Anyone whose
build resolved a fresh version inside that window — a
cargo update, a cache-cold CI job, a new
checkout — got the payload. Everyone pinned to a known-good
Cargo.lock that didn't re-resolve did not.
245M+
lifetime downloads of arrayref, the flagship poisoned crate
3
crates hit — arrayref, internment, append-only-vec
~90 min
live window before crates.io yanked the versions
build time
payload ran during cargo build, before your code compiled
The OrbitalReg defence
This is the control the 90-minute window was built to defeat — and the one that answers it. Hold new upstream crate versions for N hours before serving them through your OrbitalReg proxy. A version that lives for 90 minutes upstream never reaches a build if your quarantine is longer than its lifespan.
Developers and CI resolve crates against your OrbitalReg proxy,
not crates.io directly. A version published minutes ago isn't
served until it clears your remote-proxy policy — so a
same-hour poisoned arrayref release is not
automatically reachable the instant it lands upstream.
Once the poisoned versions land in the OSV/RustSec advisory
feeds, every pull of an affected version through your registry
gets a 403 instead
of the crate — fleet-wide, from one policy change, without
chasing each project's Cargo.lock.
The append-only trail answers "which builds pulled an affected version, and when" in one query — the exposure list you need in the first hour. In air-gap mode, nothing new resolves at all until you explicitly import and approve it.
cargo build where build.rs and
proc-macros cannot reach your credentials or the network — an
ephemeral, egress-restricted, credential-free build sandbox. A
registry does not execute your build, so it cannot neutralise a
malicious build script on its own. What it does is shrink the
window and the blast radius: quarantine keeps a 90-minute-old
version out of your builds entirely, the pull-gate stops it fleet-wide
the moment it's known, and the audit trail tells you exactly who was
exposed. Pair the registry with a sandboxed builder and pinned
lockfiles, and this attack has no path in.
Indicators of compromise
proc-macro2) as a build dependencyIndicators compiled from public reporting on 20–21 Aug 2026. Treat these as a starting point, not a complete list, and cross-check the RustSec advisory and the sources below.
Sources
Want a quarantine window between your builds and the next one?
cargo build.
Rico, the founder, walks through a proxy + quarantine + pull-gate layout for Cargo and your other formats — and how it pairs with a sandboxed builder so a build-time dropper has nowhere to land.