Rust Supply Chain Attack Injects Build‑Time Malware into Crates with 245M Downloads

0
2

Key Takeaways

  • On 20 August 2026 a compromised maintainer account published malicious versions of three popular Rust crates (arrayref 0.3.10, internment 0.8.7, append-only‑vec 0.1.9) that added a typosquatted dependency proc‑macro1.
  • The malicious code resided in the build script of proc‑macro1; simply building a project that resolved the dependency executed a payload without any crate code being called.
  • The Rust Security Response Team removed the offending versions within 86–107 minutes; no patched release or CVE has been issued, and there is no evidence the malicious versions were actually used.
  • Indicators of compromise include specific IP addresses, file paths, and binaries; the attack infrastructure overlaps with known North Korean supply‑chain operations.
  • Developers should audit their ~/.cargo/registry/cache, pin arrayref to 0.3.9 or earlier, and consider enabling forthcoming Cargo cooldown features to mitigate similar risks.

Overview of the Supply‑Chain Attack
The Rust Project discovered that a compromised owner account had pushed tainted releases of three widely used crates—arrayref, internment, and append-only‑vec—on 20 August 2026. Each release added a single line to its Cargo.toml manifest: a dependency on proc‑macro1, a deliberate typosquat of the legitimate proc‑macro2 crate. Because the malicious code lived exclusively in the build script of proc‑macro1, any Cargo command that resolved the dependency (e.g., cargo build, cargo check, cargo test) would download and execute the payload, even if the dependent crate’s own API was never invoked.

Timeline of the Malicious Releases
The three affected versions were published and removed within a narrow window:

  • arrayref 0.3.10 published 07:15:00 UTC, deleted 08:41:40 UTC (≈86 minutes online).
  • internment 0.8.7 published 07:34:07 UTC, deleted 09:04:11 UTC (≈90 minutes online).
  • append-only‑vec 0.1.9 published 07:37:49 UTC, deleted 09:25:24 UTC (≈107 minutes online).
    All were taken down by the Rust Security Response Team after being alerted at 07:15 UTC by Nextron Systems GmbH researchers.

How the Payload Operates
Proc‑macro1’s source is a verbatim copy of proc‑macro2, so compilation proceeds normally. Its build script, however, reconstructs a command‑and‑control (C2) address from Base64 fragments at build time. It then installs a custom certificate verifier that unconditionally returns success, effectively disabling TLS validation. Depending on the target OS and CPU architecture, the script selects one of four payloads: on Unix/macOS it writes an executable to /tmp/rust-setup and runs it detached with the C2 address as an argument; on Windows it drops a PowerShell script to %TEMP%\rust-setup.ps1, launches it hidden via a VBScript launcher under wscript.exe, and abandons the child process to evade Cargo’s job‑object tracking.

Delivery Mechanism via Yanked Versions
The attacker maximized the chance of accidental use by yanking the benign earlier releases (arrayref 0.3.5 through 0.3.9) in the same minute as publishing the malicious 0.3.10. Cargo’s default warning about updating to a yanked version is suppressed when the only non‑yanked option is the malicious release, thereby luring unsuspecting developers into pulling the compromised version. This “yank‑and‑replace” tactic was highlighted by the reporter (GitHub user jhobern) as the vector that led to the discovery.

Dependency‑Chain Analysis
Investigations showed that many downstream projects could resolve the malicious version through ordinary semantic versioning. For example, the chain winit → sctk-adwaita ^0.10.1 → tiny-skia ^0.11 → arrayref ^0.3.6 accepts any 0.3.x release, including 0.3.10. Similarly, blake3 listed arrayref as a dependency up to version 1.8.6; the drop in 1.8.7 (and subsequent drops in blake2b_simd and blake2s_simd) occurred later that morning, indicating a narrow window where the malicious version could have been pulled. At the time of writing, arrayref had amassed over 245 million lifetime downloads and 53.9 million in the preceding 90 days, with 403 distinct crates depending on it.

Indicators of Compromise (IoCs)
Security firms StepSecurity and Wiz published IoCs to aid detection:

  • Network: 23.254.165.112:9089 (payload host) and 23.254.165.112:443 (C2), plus the domain hwsrv-798836.hostwindsdns.com.
  • Files: /tmp/rust-setup (on *nix), %TEMP%\rust-setup.ps1 and %TEMP%\rust-setup-launch.vbs (on Windows).
  • Binaries: rust-crate_0.1.0 through _rust-crate_0.4.0.
  • Accounts: dtolney (crates.io id 438608, an impersonator) and droundy (the legitimate owner, presumed compromised).
  • Email:[email protected] (forged author metadata).
    Wiz noted that the infrastructure overlaps with recent North Korean supply‑chain campaigns, such as the Mastra npm and axios compromises, although no actor has been publicly attributed to this specific incident.

Response and Mitigation Guidance
The Rust Security Response Team advises developers to inspect ~/.cargo/registry/cache for any of the removed crate versions and to pin arrayref to 0.3.9 or earlier until a clean release is available. Since no patched version exists, pinning is the only reliable preventive measure. The team also confirmed that the maintainer’s credentials or workstation are likely compromised and are attempting to contact the legitimate owner. No CVE has been assigned, and RustSec advisories for the three crates record no observed exploitation.

Broader Context and Related Threats
This event follows a pattern of supply‑chain attacks targeting language package registries. In September 2025, two malicious crates masquerading as a logging library executed only at runtime, a distinction that crates.io highlighted at the time. The current attack differs by executing at build time via a compromised dependency’s build script, making it harder to detect with typical runtime‑only scanners. A Cargo feature request to introduce a global min-publish‑age setting—which would temporarily block newly published versions—had entered its final comment period on 18 August 2026, two days before the incident, but remained unmerged as of 21 August. GitHub’s Dependabot already shipped a similar cooldown default in July 2026, suggesting that upcoming Cargo mitigations could reduce the risk of such “yank‑and‑replace” lures.

Outlook and Recommendations
While the malicious versions were swiftly removed and no confirmed usage has been reported, the incident underscores the importance of vigilant dependency management. Teams should:

  1. Regularly audit lockfiles for unexpected or recently published versions.
  2. Employ tools that inspect build scripts (e.g., cargo deny, crev) for suspicious activity.
  3. Consider adopting upcoming Cargo cooldown mechanisms once stabilized.
  4. Maintain strict credential hygiene for crate owners (2FA, token rotation) to limit account takeover.
    By integrating these practices, the Rust ecosystem can better defend against future build‑time supply‑chain threats.

SignUpSignUp form

LEAVE A REPLY

Please enter your comment!
Please enter your name here