Skip to content

Back to the catalog

Rust Supply-Chain Attack: arrayref, internment, and append-only-vec Poisoned by the proc-macro1 Build-Time Dropper
stepsecurity.iowriteup

Rust Supply-Chain Attack: arrayref, internment, and append-only-vec Poisoned by the proc-macro1 Build-Time Dropper

StepSecurity's forensic writeup on a compromised crates.io maintainer account that published poisoned releases of arrayref (245M downloads), internment, and append-only-vec, each pulling in proc-macro1, a typosquat of proc-macro2 impersonating David Tolnay whose build.rs silently drops and executes a cross-platform stage-2 payload at compile time. The attacker also mass-yanked clean arrayref versions to funnel Cargo's "yanked" warning toward the one poisoned release, and StepSecurity reproduced the attack in GitHub Actions with Harden-Runner, capturing the C2 callback to 23.254.165.112:9089 and demonstrating automatic blocking via a global IOC block list. The post includes the full attack timeline, dropper base64-obfuscated URL scheme, SHA-256 hashes, C2 IOCs, and remediation/detection guidance for lockfiles and CI caches.

TL;DR A compromised crates.io account plus a same-day proc-macro2 typosquat poisoned arrayref, internment, and append-only-vec with a build.rs dropper that fetches and runs a C2 payload at compile time, exploiting Cargo's yank warning as the delivery lure.
Document

What it is

A crates.io supply-chain compromise (2026-08-20) affecting three legitimate crates published from one hijacked maintainer account — arrayref 0.3.10, internment 0.8.7, and append-only-vec 0.1.9 — plus attacker-owned dropper and staging crates. The vector is proc-macro1, a typosquat of proc-macro2 impersonating David Tolnay, whose build.rs executes at compile time.

How it works

The poisoned crates contain no malicious source. The only change is a manifest edit adding proc-macro1@1.0.107 as a dependency. That crate ships genuine proc-macro2 source (so builds and tests pass) but carries a cross-platform build.rs dropper: it downloads a second-stage binary over TLS with certificate validation disabled, writes it to a temp dir, and executes it with a C2 address as an argument. Because build scripts run during compilation, resolving the dependency in a lockfile is enough to detonate — the crate's code is never called.

The attack was staged: the impersonator persona was created that morning with a clean decoy release ~5 hours before weaponization; the malicious arrayref went live 4 minutes after its dependency; and in the same minute, all clean arrayref 0.3.x releases were yanked in a scripted burst, turning Cargo's "yanked version" warning into a funnel toward the one remaining poisoned release.

Preconditions / Affected

Any cargo build, cargo update, or CI run that resolved a poisoned version during the exposure window. Per-crate windows total 86/90/107 minutes; overall window 07:11–09:25 UTC on 2026-08-20. Blast radius: 406 dependent crate versions; 264M combined all-time downloads. arrayref sits under tiny-skia, winit, blake3, and Solana/Ethereum tooling.

What to do

If arrayref 0.3.10, internment 0.8.7, append-only-vec 0.1.9, or any version of proc-macro1 or proc-macro-en was resolved between 07:11 and 09:25 UTC on 2026-08-20, assume that machine is compromised.

Pin to the last safe versions:

  • arrayref → 0.3.9
  • internment → 0.8.6
  • append-only-vec → 0.1.8

IOCs to hunt: dependency on proc-macro1 or proc-macro-en in any lockfile; the attacker-owned crates aovine, arone, aronenao, tinymember. Note arone (7 versions) and aronenao (11 versions) were published 2026-08-18 — two days earlier — and also ran malicious build scripts, so exposure may predate the arrayref push.

Caveats

  • Taking down proc-macro1 did not disarm the campaign — proc-macro-en shipped the same build script.
  • tinymember was deleted by association only; it contained no malicious code and had no dependents.
  • The maintainer is not believed malicious; their machine/credentials are assessed as compromised and the account locked.
  • StepSecurity's investigation is described as ongoing; all malicious versions are now removed and maliciously yanked releases restored.

Organisations named here

  • advisory-db#3161
  • David Tolnay
  • droundy
  • Hostwinds
  • jhobern
  • Nextron Systems GmbH
  • Rust Security Response Team

Technologies named here

  • arrayref
  • StepSecurity Harden-Runner
  • internment
  • StepSecurity Threat Center
  • append-only-vec
  • cargo audit
  • cargo vet
  • proc-macro1
  • proc-macro-en
  • RustSec advisory database
  • grep
  • aovine
  • arone
  • find
  • aronenao
  • tinymember
  • proc-macro2
  • tiny-skia / tiny-skia-path
  • sctk-adwaita
  • winit
  • egui / eframe / iced
  • blake3
  • blake2b_simd / blake2s_simd
  • revm-precompile
  • spl-token / solana-runtime
  • Rust
  • Cargo
  • crates.io
  • GitHub Actions
  • StepSecurity
  • Harden-Runner
  • RustSec

Techniques named here

  • Build-time dependency supply-chain compromise
  • Maintainer account compromise
  • Typosquatting
  • Identity impersonation / persona staging
  • Decoy/reputation-laundering release
  • Yank-and-upgrade lure
  • String obfuscation via base64 fragmentation
  • TLS certificate validation bypass
  • Detached process spawning / job-object evasion
  • Platform-specific payload delivery
  • Persistence via systemd service and disguised binaries
  • Transitive dependency poisoning

Threat actors named here

  • dtolney
  • Unnamed attacker/campaign operator
  • Account owning arone/aronenao/tinymember
  • rust-setup / rust-crate dropper malware family