Back to Blog

Rust Supply-Chain Attack: arrayref 0.3.10 and the proc-macro1 Typosquat Execute a Remote Payload at Build Time

A compromised arrayref 0.3.10 release pulled in a typosquatted proc-macro1 crate that runs a remote payload during cargo build. This is a developing story and we are actively investigating.
Sai Likhith
View LinkedIn

August 20, 2026

Share on X
Share on X
Share on LinkedIn
Share on Facebook
Follow our RSS feed
arrayref supply chain compromise, developing story, StepSecurity Threat Intelligence
Table of Contents

Summary: compromised package, active investigation

The Rust crate arrayref version 0.3.10 is compromised. Published on 2026-08-20 at 07:15 UTC, it silently added a dependency on proc-macro1 1.0.107, a typosquat of the ubiquitous proc-macro2, whose build script downloads a binary from https://23.254.165.112:9089/ and executes it on any machine that builds the crate. Because the malicious code lives in build.rs, simply compiling a project is enough to run the payload; nothing from the crate needs to be called. We are actively investigating this incident together with the Rust security community. crates.io has since deleted both malicious releases, but anyone who refreshed a lockfile during the exposure window should assume compromise. Indicators of compromise and remediation steps are below.

What happened

  • 01:17: A GitHub account named dtolney is created, impersonating David Tolnay (dtolnay), author of the real proc-macro2.
  • 01:25: The matching crates.io account dtolney is created.
  • 01:55: proc-macro1 1.0.106 is published: a clean, verbatim copy of proc-macro2. Pure staging; it builds a plausible, benign crate under the squatted name.
  • 07:11: proc-macro1 1.0.107 is published, adding build dependencies (base64, rustls, ureq) that no genuine proc-macro library needs.
  • 07:15: arrayref 0.3.10 is published from the account of its owner, droundy, adding the first real dependency in the crate's decade-long history: proc-macro1 ^1.0.107. Within the same minute, versions 0.3.5 through 0.3.9 are yanked in a scripted burst (~4 seconds apart), so Cargo's "yanked version" warning nudges users to upgrade into the trap.
  • 07:54: The incident is reported to the RustSec advisory database and the Rust security team.
  • 08:03: crates.io deletes proc-macro1.
  • 08:41: crates.io removes arrayref 0.3.10 from the index. Exposure window: roughly 86 minutes.

The droundy account, which belongs to a maintainer in good standing since 2009, is presumed compromised, and the associated GitHub account was returning 404 at the time of writing. The attacker's persona was fabricated the same morning, complete with forged author metadata (David Tolnay <rchaitm@gmail.com>) and a nonexistent repository link.

How the attack works

The malicious build.rs in proc-macro1 1.0.107:

  • Reassembles its infrastructure from base64 fragments: a payload host (https://23.254.165.112:9089/) and a command-and-control endpoint (23.254.165.112:443).
  • Fetches a stage-2 binary over TLS with certificate validation explicitly disabled (an accept-all verifier), choosing among rust-crate_0.1.0 through _0.4.0 by target platform.
  • Drops it to /tmp/rust-setup on Unix, or %TEMP%\rust-setup.ps1 via a hidden wscript.exe launcher on Windows, and spawns it detached with the C2 address as an argument, carefully escaping Cargo's job object so the build finishes without waiting and nothing looks suspicious.
  • Meanwhile the library code itself is genuine proc-macro2, so builds succeed and the infection is invisible in normal output.

The payload host is a Hostwinds VPS (hwsrv-798836.hostwindsdns.com). The stage-2 payload's behavior is still being analyzed.

Why it matters: blast radius

arrayref is a foundational utility crate with roughly 245 million all-time downloads. The reporter traced the chain tiny-skiasctk-adwaitawinit, putting the malicious release underneath egui/eframe, iced, and most Rust GUI applications. Our reverse-dependency check shows the reach is broader still: dependents include blake3, blake2b_simd/blake2s_simd, revm-precompile (Ethereum), and solana-runtime/spl-token (Solana). Any CI job or developer build that resolved arrayref ^0.3 fresh during the 86-minute window executed the payload with that user's privileges.

Am I affected? What to do now

  • Check your lockfiles: grep -A2 'name = "arrayref"' Cargo.lock. Version 0.3.10, or any entry named proc-macro1, means the payload ran on that machine.
  • Look for artifacts: /tmp/rust-setup, %TEMP%\rust-setup.ps1, %TEMP%\rust-setup-launch.vbs, and any network egress to 23.254.165.112 (ports 9089 or 443).
  • If you find evidence: treat the host as compromised. Rotate every credential, token, and key reachable from it, including CI secrets and signing keys, and rebuild any artifacts produced after exposure from clean sources.
  • If you are clean: pin arrayref = "=0.3.9" (yanked versions remain downloadable for existing lockfiles) and never resolve yank warnings by blind upgrades. Note that Cargo currently resolves arrayref ^0.3 to the 2017-era 0.3.4 until the maintainer situation is sorted out.

Indicators of compromise

Network:   23.254.165.112:9089 (payload host)
          23.254.165.112:443  (C2, passed to payload as argv[1])
          hwsrv-798836.hostwindsdns.com
Files:     /tmp/rust-setup
          %TEMP%\rust-setup.ps1
          %TEMP%\rust-setup-launch.vbs
Binaries:  rust-crate_0.1.0 / _0.2.0 / _0.3.0 / _0.4.0
Crates:    arrayref 0.3.10, proc-macro1 1.0.106 and 1.0.107
Accounts:  dtolney (crates.io id 438608), impersonator
          droundy, legitimate owner, presumed compromised
Email:     rchaitm@gmail.com (forged author metadata)
SHA-256:   25ad700976873c76af785cb99b33c48db7df8b81f21d1e9e06b3676b9a9373ae  arrayref-0.3.10.crate
          61198155da51b838772eecf5bfaac6cbc4dcc388dccc56658fc28a8e831b34d4  proc-macro1-1.0.107.crate
          b5c1b5b0763a8809a644a8f92224653f0aca623a98eecc714d27f74b80fbe436  proc-macro1-1.0.106.crate

Reference


rustsec advisory-db

Explore Related Posts