On August 20, 2026, malicious versions of three Rust crates were published to crates.io from the account of their maintainer, droundy: arrayref@0.3.10, internment@0.8.7 and append-only-vec@0.1.9. The Rust Security Response Team does not believe the maintainer published them, assesses that their machine or credentials were compromised, and has locked the account.
arrayref is a widely depended-on utility crate. Its reverse dependencies include blake3, the tiny-skia → sctk-adwaita → winit chain underlying most Rust GUI applications, and packages in the Ethereum and Solana ecosystems.
The malicious arrayref added proc-macro1 as a dependency, the first dependency in the crate's ten-year history. proc-macro1 is a typosquat of proc-macro2, published earlier the same morning by dtolney, a new account impersonating dtolnay, the author of the legitimate crate. Five additional attacker-controlled crates were deleted alongside it: proc-macro-en, aovine, arone, aronenao and tinymember.
The earlier versions of each hijacked crate were yanked at the same time. Cargo warns when a pinned version is yanked, and upgrading in response to that warning resolves the project onto the malicious version.
The malicious code is contained entirely in proc-macro1's build script, which pulls in three build dependencies a proc-macro library has no reason to need: base64, rustls and ureq. The script reconstructs a download server and a command-and-control address from base64 fragments, retrieves a second-stage payload over HTTPS with certificate validation disabled, and writes it to /tmp/rust-setup on Linux and macOS or %TEMP%\rust-setup.ps1 on Windows, where a hidden wscript.exe call executes it. The payload runs detached from Cargo with the C2 address as its argument, so the build completes without waiting on it. The remainder of the crate is a genuine copy of proc-macro2, so builds succeed and produce no unusual output. Execution requires no call into the crate; compilation alone is sufficient.
The stage-2 payload is an infostealer and remote access tool, delivered as one of four platform-specific builds served as OpenSSL-encrypted archives: rust-crate_0.1.0 for Linux x64, _0.2.0 for Windows x64, _0.3.0 for macOS x64 and _0.4.0 for macOS arm64. It collects hostname, username and operating system details, enumerates installed applications, and reads Chrome, Brave and Edge profiles for saved logins and extension settings, querying the browsers' SQLite credential stores directly. It installs persistence as a systemd user service on Linux, an HKCU Run registry entry on Windows and a LaunchAgent on macOS.
The payload reports to its command-and-control server over HTTPS with a POST to /49890878 and a base64-encoded JSON body, and accepts commands to reconfigure itself, install persistence, terminate, and download and execute arbitrary scripts in the foreground or detached. Commands are authenticated against an embedded 2048-bit RSA key and the local configuration is encrypted with AES-128-GCM under a hardcoded key, so recovered configuration files can be decrypted. If the primary server is unreachable, the payload derives ten fallback domains per five-day window from a time-seeded algorithm, so a fixed domain blocklist will not hold. Wiz Threat Research analysis identified a second command-and-control address, 23.254.167[.]107:443, live at the time of publication and distinct from the address the build script supplies.
Each malicious version was available for under two hours before the Rust Security Response Team removed it, and the maliciously yanked versions have been restored. Only builds that resolved dependencies from scratch or ran cargo update within that window are affected; projects with an existing Cargo.lock were not moved onto a malicious version. Nextron Systems discovered and reported the attack.