arrayref 0.3.10 Malware: Check Rust Builds and CI

Brendan Smith
Brendan Smith - Cybersecurity Analyst
8 Min Read
Three Rust crates linked by the malicious proc-macro1 dependency enter a build conveyor.
The malicious proc-macro1 dependency turned three Rust package builds into a payload-delivery path.

The Rust Security Response Team removed malicious releases of arrayref 0.3.10, internment 0.8.7, and append-only-vec 0.1.9 from crates.io on August 20. Each poisoned release pulled in a malicious dependency named proc-macro1, whose build script downloaded and launched a payload while Cargo compiled a project. Developers should check resolved lockfiles, local Cargo caches, and CI build history—not just update the dependency and assume the incident is over. [1]

The decisive boundary is whether a build ran. A matching crate in Cargo.lock or ~/.cargo/registry/cache proves that the bad version was resolved or downloaded, but not by itself that its build script executed. If a developer workstation or CI runner actually built a project with one of the malicious versions, treat that host as compromised and rotate every secret it could access from a clean system.

Which Rust crate versions were malicious?

Deleted release Exposure and current action
arrayref 0.3.10 Online for 86 minutes, from 07:15:00 to 08:41:40 UTC. Pin or resolve to a trusted release such as 0.3.9, then verify the lockfile and every cache used by local and CI builds.
internment 0.8.7 Online for 90 minutes, from 07:34:07 to 09:04:11 UTC. Use a trusted release such as 0.8.6 and inspect whether the poisoned version reached a build host.
append-only-vec 0.1.9 Online for 107 minutes, from 07:37:49 to 09:25:24 UTC. Use a trusted release such as 0.1.8 and check direct and transitive resolution.
proc-macro1, proc-macro-en, aovine, arone, aronenao, or tinymember The Rust team deleted every version of these attacker-controlled or associated crates. Any hit needs investigation; do not confuse proc-macro1 with the legitimate proc-macro2.

The publication windows are short, but lifetime download totals do not measure infected computers. Existing applications with a clean, committed lockfile could keep using the clean version even while an attacker had yanked it. The risk is concentrated on fresh resolution, lockfile refreshes, dependency updates, unpinned builds, warm caches containing a deleted release, and any build that ran after one of those versions was selected.

How the build-time malware chain worked

The attacker did not need to hide malicious logic inside the visible arrayref macros. Version 0.3.10 added a dependency on the lookalike proc-macro1 package. Cargo builds declared dependencies even when the parent crate never calls them, so the malicious build.rs ran during compilation. The script reconstructed a download address, disabled normal TLS certificate validation, fetched a platform-specific payload, and started it as a detached process. [2]

On Unix-like systems the first-stage file was written as /tmp/rust-setup. On Windows, the reported path was %TEMP%\rust-setup.ps1, launched through %TEMP%\rust-setup-launch.vbs and wscript.exe. Researchers reproduced the payload download during a monitored build, which is why a successful compile with the poisoned dependency should be treated as code execution—not merely a vulnerable package sitting unused in a project. [3]

Check lockfiles and Cargo caches

  1. Search every repository. Inspect committed and generated Cargo.lock files for the three exact malicious versions and for any of the deleted attacker-owned crate names.
  2. Check developer and CI caches. The Rust team supplied the following cache search. Run it for each developer account, self-hosted runner, container layer, and restored CI cache that could have built Rust code.
find ~/.cargo/registry/cache -type f \( \
  -name 'append-only-vec-0.1.9.crate' -o \
  -name 'arrayref-0.3.10.crate' -o \
  -name 'internment-0.8.7.crate' -o \
  -name 'proc-macro1-*.crate' -o \
  -name 'proc-macro-en-*.crate' -o \
  -name 'aovine-*.crate' -o \
  -name 'arone-*.crate' -o \
  -name 'aronenao-*.crate' -o \
  -name 'tinymember-*.crate' \
\) -print
  1. Separate download from execution. A cache hit means the crate was downloaded. Correlate it with shell history, build logs, job timestamps, cache restore records, and artifacts to determine whether cargo build, cargo test, packaging, or another compile step ran.
  2. Review network and file evidence. Search historical egress for 23.254.165.112 on ports 9089 or 443. Check for the reported Unix and Windows first-stage files, but do not use their absence as proof that no payload ran.

What to do if a poisoned Rust build ran

  1. Stop reuse of the host. Isolate a developer workstation or self-hosted runner from sensitive networks. Disable the affected pipeline while preserving build logs, lockfiles, caches, process telemetry, and egress records.
  2. Map reachable secrets. List GitHub and GitLab tokens, crates.io publishing tokens, cloud credentials, SSH keys, signing keys, deployment secrets, package-registry credentials, wallet material, and environment variables available to the user or CI job.
  3. Rotate from a clean system. Revoke sessions and replace exposed credentials in dependency order. Changing a token on the suspected host can hand the replacement to active malware.
  4. Rebuild the environment. Replace ephemeral runners from trusted images, rebuild persistent hosts when integrity cannot be established, purge poisoned Cargo caches and vendored copies, and recreate dependencies from trusted lockfiles.
  5. Rebuild deliverables. Treat binaries, installers, containers, and signed artifacts produced after the poisoned build as untrusted until they are rebuilt on clean infrastructure and compared with expected provenance.

On a Windows developer workstation, a full Gridinsoft Anti-Malware scan can help find detected payloads, startup entries, scheduled tasks, services, and other persistence after containment. A clean endpoint scan cannot invalidate stolen tokens or prove that a detached process never ran, so credential rotation and a trusted rebuild remain separate requirements.

Do not mistake removal from crates.io for cleanup

Deleting the malicious releases prevents normal fresh downloads, but a warm Cargo cache, vendored dependency directory, container layer, or internal registry mirror can retain the files. Updating Cargo.toml also does not clean a machine that already executed the build script. Confirm the resolved version, purge retained copies, investigate the host, rotate reachable secrets, and rebuild affected artifacts.

The legitimate proc-macro2 crate is not the malicious package described here. The name collision matters because a broad search for “proc macro” can create unnecessary incident work. Match exact package names and versions before escalating. For a different cross-ecosystem package attack, see the TrapDoor npm, PyPI, and crates.io response guide; the Jscrambler compromise guide explains why secret rotation must follow execution scoping instead of replacing it.

References

  1. Rust Security Response Team. “Supply chain attack on arrayref.” Rust Blog, August 20, 2026. Affected releases, removal times, and cache-check guidance.
  2. jhobern. “Malware: arrayref 0.3.10 executes a remote payload at build time via typosquatted proc-macro1.” RustSec Advisory Database issue 3161, August 20, 2026. Initial report, build-script behavior, and indicators.
  3. Sai Likhith. “Rust Supply-Chain Attack: arrayref, internment, and append-only-vec Poisoned by the proc-macro1 Build-Time Dropper.” StepSecurity, updated August 20, 2026. Runtime reproduction, dependency chain, and response analysis.
Share This Article
Cybersecurity Analyst
Follow:
Brendan Smith has spent over 15 years knee-deep in cybersecurity, chasing down malware from the gritty reverse-engineering of old-school trojans all the way to wrangling full-blown incident responses for small-to-medium businesses that couldn’t afford a full-blown breach. Over at Gridinsoft, he’s the guy piecing together those double-checked guides on nasty stuff like AsyncRAT ransomware—take last year, for instance, when his breakdowns caught more than 200 sneaky variants right in live scans, knocking user cleanup jobs down by a solid 40% and saving folks hours of headache.
Leave a Comment

AI Assistant

Hello! 👋 How can I help you today?