The Rust Security Response Team says a routine Cargo update became a short supply-chain attack on 20 August 2026, after releases from the legitimate maintainer account were used to introduce malicious dependencies.[1] The team says it does not believe the maintainer acted maliciously and assesses that the maintainer’s computer or credentials were likely compromised.[1] The target was a small Rust utility, arrayref, plus two related crates, and the malicious code ran while dependent projects were being compiled.[4]
The incident matters because the library source could still look normal.[2][4] The dangerous change was in the package manifest, which added a dependency on a typosquat of the legitimate proc-macro2 crate. Cargo’s documented build-script lifecycle explains how that dependency could execute code before the package build completed.[7]

What was published
The Rust Security Response Team says the malicious versions were arrayref 0.3.10, internment 0.8.7 and append-only-vec 0.1.9.[1] It removed those releases, deleted the attacker-controlled crates proc-macro1, proc-macro-en, aovine, arone, aronenao and tinymember, and locked the maintainer account as a precaution.[1]
The registry records the short exposure windows.[1] arrayref 0.3.10 was published at 07:15 UTC and removed at 08:41, while internment 0.8.7 lasted from 07:34 to 09:04 and append-only-vec 0.1.9 from 07:37 to 09:25.[1] These are not estimates of the number of infected machines. They are the periods during which the affected releases were available from the registry.[1]
The public registry now shows arrayref 0.3.9 as the default and newest version, with the earlier releases restored after the response.[3] That current state should not be confused with proof that no machine used the deleted version. A registry cleanup changes what can be downloaded now, not what was already cached or built.[1][3]
The important change was one dependency line
The RustSec report says arrayref 0.3.10 introduced its first dependency, proc-macro1 1.0.107.[2] The name differs from proc-macro2 by one character, while the package copied the genuine crate’s library source closely enough to keep normal compilation working.[2][4]
The malicious behaviour lived in proc-macro1‘s build.rs, not in the ordinary arrayref macros.[4] SafeDep’s analysis describes a build script that reconstructs a remote address from encoded fragments, downloads a platform-specific payload and starts it during compilation.[4] Wiz reports support for Linux x86_64, Windows x86_64, macOS x86_64 and macOS arm64.[5]
That detail changes the usual mental model of a dependency compromise. A developer did not need to call an affected function, run a test that exercised a particular code path, or deploy the resulting application. The execution condition was a build that caused the affected package’s malicious build.rs to run.[7] Resolution, downloading a registry archive, seeing a version in a lockfile, or compiling from an already-completed build state did not by themselves prove that the script ran.[7][8]
Why the package graph hid the attack
arrayref is a transitive dependency, which means it can enter a project through another library rather than an explicit line in the project’s manifest.[2] The RustSec report places it below components such as tiny-skia, sctk-adwaita and winit, with consequences for projects built around egui, eframe and iced.[2]
The registry reports more than 245 million lifetime downloads for arrayref, but that number is a measure of distribution, not an incident count.[3] It tells us that the package is widely present in the ecosystem. It does not tell us how many projects resolved 0.3.10 during the exposure window, how many compiled it, or how many hosts reached the payload server.[1][3]
The delivery sequence also involved yanked releases. The current crates.io audit records place the yanks of arrayref 0.3.9, 0.3.8, 0.3.7, 0.3.6 and 0.3.5 at 07:15:24, 07:15:26, 07:15:30, 07:15:36 and 07:15:40 UTC respectively.[3] RustSec reports arrayref 0.3.10 as published at 07:15 UTC and records that a yanked-version warning helped steer one reporter towards the remaining release.[2]
The current API no longer exposes the deleted 0.3.10 version, so it cannot independently reconstruct that version’s complete registry record. The available evidence nevertheless places the ordered yank burst after the 07:15 publication time reported by RustSec, while leaving the full historical delivery sequence unresolved.[2][3] Cargo documents that yanking prevents normal new resolution without an existing lockfile, but does not delete the package or affect direct downloads and existing lockfiles.[8]
This is the useful distinction: a lockfile can make builds reproducible, but it cannot make a newly resolved package trustworthy.[3] Reproducibility fixes the question “what did we build?” It does not, by itself, answer “was that artifact safe when we built it?” Cargo may also avoid rerunning an unchanged build script, so a lockfile entry, a cached archive and a completed build are separate evidence states.[7][8]
What the payload was designed to do
SafeDep and Wiz describe a two-stage design in the technical analyses cited here.[4][5] They report that the build script downloaded a second-stage binary, wrote it to a temporary location and launched it separately from the compiler. On Unix-like systems the reported path was /tmp/rust-setup; on Windows the chain used files under %TEMP% and a hidden script launcher. These are reported or statically analysed behaviours in those two analyses, not a public count of confirmed executions on affected hosts.
Wiz’s analysis describes host and operating-system discovery, persistence mechanisms for Windows, macOS and Linux, and command handling that could support further actions.[5] These statements describe reported payload capabilities, not proof that every capability ran on every affected host. The analysis also describes queries against Chrome, Brave and Edge profile databases, and clarifies that the queries enumerated saved-login records but did not retrieve the encrypted credential material itself.[5]
The listed Linux and macOS architectures should be read as environments examined by the payload analysis, not as a complete target-platform impact matrix. Cargo states that build scripts run on the host environment, which matters when a project is cross-compiled.[7]
That clarification is important.[5][6] One contemporaneous report described the capability more broadly as credential collection. The more specific reverse-engineering account supports saying that browser profile data was queried and that the payload had credential-related collection logic, but it does not justify claiming that usable browser passwords were necessarily exfiltrated from every affected host.
The incident reports also identify a payload host at 23.254.165.112, ports 9089 and 443, and dropped-file names that defenders can use for retrospective checks.[4][5] Network indicators can age quickly, so they are evidence for a historical investigation rather than a complete detection strategy.
What teams should check first
The Rust team recommends searching the local Cargo cache for the affected versions and attacker-controlled package names.[1] The following checks are the article’s incident-response synthesis, not an additional instruction issued by the Rust team. A clean current registry does not erase evidence of an earlier resolution, cache hit or build.[3][7]
A practical triage sequence follows from the attack path.[1][4][5]
- Package and lockfile evidence: search
Cargo.lockfiles and structured dependency reports forarrayref0.3.10,internment0.8.7,append-only-vec0.1.9,proc-macro1,proc-macro-en,aovine,arone,aronenaoandtinymember.[1][5] A match in a lockfile or graph report records a dependency resolution, not a download, build-script execution, payload retrieval, payload launch or host impact. - Cache evidence: check Cargo caches and CI artefacts for the same package names, including deleted packages that may remain on disk.[1][5] A cached archive proves local availability, not compilation.
- Build evidence: look for Cargo build output,
targetbuild directories and CI logs showing that the affected package was actually built. Cargo says build scripts run just before their package is built and that their output is saved under the target build directory.[7] Absence of an output file is not proof that no build occurred, especially after cleanup. - Host evidence: if build logs, network telemetry, dropped files or another forensic artefact establish that the malicious
build.rsran or that it attempted the payload download, treat the developer machine or runner as potentially compromised. The response recommendation to rotate reachable credentials, CI tokens and signing keys applies when execution or host indicators support exposure, not merely because a package name appears in a lockfile.[2][5][7] - Historical evidence: preserve logs, network telemetry and dropped-file evidence before cleanup. The reported indicators include
23.254.165.112, ports 9089 and 443,/tmp/rust-setup, and the Windows temporary-file paths.[4][5] These indicators support retrospective investigation and do not establish universal impact.
Package presence, build execution and host impact are separate evidence states. Treating them separately avoids both false reassurance from a clean current registry and the unsupported claim that every historical download became an infection.[1][2][7]
The broader lesson is about build trust
The article’s inference is that Rust’s memory-safety guarantees do not protect a build environment from arbitrary actions performed by a package’s build script. Cargo’s documentation confirms that build scripts run before package compilation and can perform tasks in the build environment.[4][7] The affected library code could remain functionally correct while its build-time dependency made network requests.[4]
This incident illustrates a general build-system trust boundary: source review, dependency resolution, compilation and runtime execution are different stages.[7] A review that inspects only the library’s exported functions can miss a malicious manifest change. A security process that checks only production binaries can miss a developer workstation or CI runner compromised before the binary was produced.[4][5]
Forensic work should begin with the package/version/hash tuple and the strongest available evidence state, then move towards build and host telemetry.[1] Network restrictions can block a second-stage download, but they do not prove that the package was safe; a blocked build and a clean build are different outcomes.[7][8] The deleted release is no longer the whole incident. The build history is.
What the public record cannot show
The public sources establish the affected versions, publication windows, package manifests, reported payload behaviour and indicators. They do not provide a public count of affected hosts, completed builds, exfiltrated credentials or confirmed persistence events across all victims.[1][4][5]
The browser-query wording also requires care. BleepingComputer used broader credential-collection language, while Wiz’s later technical qualification says the analysed queries enumerated saved-login records without retrieving encrypted credential material.[5][6] This article treats the payload capabilities as reported technical analysis, not as proof of universal credential exfiltration.
Reported SHA-256 indicators
arrayref0.3.10: SHA-25625ad700976873c76af785cb99b33c48db7df8b81f21d1e9e06b3676b9a9373ae.[4][5] This is a cross-published forensic identifier, not a hash independently recalculated here from a recovered archive.proc-macro11.0.107: SHA-25661198155da51b838772eecf5bfaac6cbc4dcc388dccc56658fc28a8e831b34d4.[4][5] This is likewise reported by the technical analyses.- Reported payload host:
23.254.165.112, ports 9089 and 443.[4][5] - The crates.io API snapshot consulted on 21 August 2026 reports 245,385,500 lifetime downloads for
arrayref. That is a distribution measure, not an incident measurement.[3]
Sources
- https://blog.rust-lang.org/2026/08/20/supply-chain-attack-on-arrayref
- https://github.com/rustsec/advisory-db/issues/3161
- https://crates.io/api/v1/crates/arrayref
- https://safedep.io/arrayref-proc-macro1-rust-build-time-malware
- https://www.wiz.io/blog/rust-supply-chain-attack-on-arrayref-significant-overlap-with-dprk-campaigns
- https://www.bleepingcomputer.com/news/security/hackers-poison-arrayref-rust-crate-to-push-infostealer-malware
- https://doc.rust-lang.org/cargo/reference/build-scripts.html
- https://doc.rust-lang.org/cargo/commands/cargo-yank.html