# arrayref and two other Rust crates poisoned via the proc-macro1 typosquat

> Compromised maintainer accounts published `arrayref@0.3.10` (244M downloads), `internment@0.8.7`, and `append-only-vec@0.1.9` to crates.io. Each release added a single dependency line on typosquat crate `proc-macro1`, whose `build.rs` downloads and executes a platform-specific payload from `23.254.165.112:9089` during `cargo build`. Wiz attributes overlap to DPRK campaigns.

- Published: 2026-08-20
- Severity: critical
- Kind: Compromise - A legitimate, already-used package, maintainer account, CI pipeline, or release tag was hijacked and a malicious version was published under a name people already depend on.
- Ecosystems: crates.io
- Scope: 5 packages, 4 compromised versions
- Tags: maintainer-takeover, account-takeover, typosquat, infostealer, credential-theft, ci-cd-compromise, obfuscation
- Threat actor: DPRK-linked (Wiz-reported infrastructure overlap with Famous Chollima / Contagious Interview campaigns)
- Also known as: arrayref supply chain attack, proc-macro1 build-time dropper, 2026-08-20 crates.io compromise, Rust arrayref internment append-only-vec attack
- Detected by: Socket, Wiz, SafeDep, Semgrep, StepSecurity, Aikido Security, Rust Security Response Team
- Incident ID: crates-2026-08-20-arrayref-proc-macro1-build-time

## Affected packages (5)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [append-only-vec](https://dependencywatch.io/package/crates/append-only-vec) | crates.io | 0.1.9 |
| [arrayref](https://dependencywatch.io/package/crates/arrayref) | crates.io | 0.3.10 |
| [internment](https://dependencywatch.io/package/crates/internment) | crates.io | 0.8.7 |
| [proc-macro-en](https://dependencywatch.io/package/crates/proc-macro-en) | crates.io |  |
| [proc-macro1](https://dependencywatch.io/package/crates/proc-macro1) | crates.io | 1.0.107 |

## What happened

On the morning of 2026-08-20 UTC, a coordinated build-time supply-chain attack landed on crates.io. Between 07:11 and 09:25 UTC, three widely-used Rust crates were republished with a single-line manifest change that pulled in a typosquat dependency called `proc-macro1`; whenever any host on the internet subsequently ran `cargo build`, `cargo update`, or a CI resolve step that touched those crates, the compromised `build.rs` fired and dropped a target-matched infostealer binary. All three crates and the dropper were yanked by the Rust Security Response Team within 3 hours, but the reach is unusually large because `arrayref` is a foundational transitive dependency across most of the Rust ecosystem (Wiz observed it in ~75% of environments where any Rust is present).

## Affected crates and takedown windows

| Crate | Malicious version | Publisher account | Published (UTC) | Yanked (UTC) | Downloads |
|---|---|---|---|---|---|
| `arrayref` | 0.3.10 | `droundy` (compromised) | 2026-08-20 07:15 | 08:41 | 244M all-time, 53.7M in 90 days |
| `internment` | 0.8.7 | (compromised maintainer) | 2026-08-20 07:34 | 09:04 | 14M all-time |
| `append-only-vec` | 0.1.9 | (compromised maintainer) | 2026-08-20 07:37 | 09:25 | 4M all-time |
| `proc-macro1` (dropper) | 1.0.107 | `dtolney` (compromised) | 2026-08-20 07:11 | 08:03 | new crate, typosquat of `proc-macro2` |
| `proc-macro-en` (dropper variant) | seen | - | 2026-08-20 window | - | new crate |

Each compromised release added a single dependency line to `Cargo.toml` naming `proc-macro1`. The **library source of `proc-macro1` is a genuine copy of `proc-macro2`**, so builds succeed with no compile-time signal - all malice sits inside `build.rs`. To create update pressure toward the poisoned `arrayref@0.3.10`, the attacker also **yanked all prior versions `0.3.5` through `0.3.9`**, so any cargo resolver rolling a `^0.3` range forward landed on the malicious release; the Rust Security Response Team subsequently un-yanked the clean prior versions after the incident.

## Payload behaviour (build.rs)

The malicious `build.rs` runs during compilation, before any code the developer wrote executes. It:

1. Reconstructs C2 URLs from **base64-encoded fragments** so a static scan for the literal IP string misses it.
2. Constructs a `rustls` client with a custom `AcceptAll` verifier (**TLS verification disabled**) so a self-signed C2 cert works.
3. Downloads a **target-specific binary** from `23.254.165.112:9089` under one of four names (`rust-crate_0.1.0`, `_0.2.0`, `_0.3.0`, `_0.4.0`) matched to Linux x86-64, Windows x86-64, macOS x86-64, macOS ARM64.
4. Passes the second C2 endpoint `23.254.165.112:443` as `argv[1]` to the executed binary for follow-up traffic.

On Unix, the payload lands at `/tmp/rust-setup` and is spawn-detached from cargo. On Windows the dropper writes `%TEMP%\rust-setup.ps1` and a VBScript launcher `rust-setup-launch.vbs`, then launches via `wscript.exe` with `CREATE_NO_WINDOW`; the dropper also calls `std::mem::forget()` on the child process handle so **the payload survives after `cargo build` completes** - the child escapes the build job object and keeps running.

## Blast radius

`arrayref` is a small primitive crate (fixed-length array reference helpers) that ended up as a foundational transitive dependency in most of the Rust ecosystem. Direct dependents include `blake3` (widely-used hash), Rust GUI frameworks (`egui`, `eframe`, `iced`), and Rust plumbing under `winit` / `sctk-adwaita` / `tiny-skia` used by nearly every native Rust GUI app. Wiz observed `arrayref` present in **~35% of all environments they scanned, and ~75% of environments where any Rust is present** - so an org that builds ANY modern Rust code (a Solana or Ethereum tool, a Tauri or Iced desktop app, a Rust-backed CLI) has a high probability of pulling `arrayref` transitively without ever writing a direct `[dependencies]` entry.

Any host that ran `cargo build`, `cargo update`, `cargo check`, `cargo test`, or CI resolution touching these crates between 07:11 and 09:25 UTC on 2026-08-20 executed the payload. This includes shared CI runners on GitHub Actions, GitLab CI, Buildkite, and self-hosted CI - a runner that resolved once and then rebuilt with cache would have executed the payload on the first build and then persistently held whatever backdoor artifacts the payload dropped.

## Attribution

Wiz reported **significant overlap with DPRK / Lazarus supply-chain infrastructure** - naming conventions and payload behaviour align with prior Famous Chollima / Contagious Interview activity that has been running against ecosystem maintainers for over a year. Both publishing accounts (`droundy` and `dtolney`) appear compromised via credential theft, not sock puppets. `droundy` is the long-standing maintainer of `arrayref` since 2015; the Rust Security Response Team locked both accounts as a precaution.

## Detectability

A passive scanner that only hashes `arrayref`'s own source misses this attack entirely - the arrayref source is unchanged. Detection requires either (a) resolving the full dependency graph and flagging previously-unseen crate names, (b) monitoring `build.rs` execution for outbound HTTP to fresh IPs, or (c) hashing `Cargo.toml` for the specific version window and alerting on the added `proc-macro1` line. This attack shape will recur; teams that rely purely on source-code hashing for supply-chain defence will keep missing it.

## Discovery credits and timeline

Socket AI Scanner (independent detection at 07:29:50 UTC, ~15 minutes after arrayref was published), Wiz Threat Research (DPRK attribution), SafeDep, Semgrep, StepSecurity, Aikido Security. RUSTSEC advisories filed via `rustsec/advisory-db#3161`. Rust Security Response Team (crates.io) took down the malicious releases and locked publishing accounts.

## Impact

- **Affected crates and windows on crates.io (2026-08-20)**: `arrayref@0.3.10` published 07:15 UTC by compromised account `droundy`, live 86 minutes, yanked 08:41 UTC (244M all-time downloads, 53.7M in last 90 days, 403 direct dependents); `internment@0.8.7` live ~90 minutes, yanked 09:04 UTC (14M downloads); `append-only-vec@0.1.9` published 07:37 UTC, yanked 09:25 UTC (4M downloads). All three added a single line to `Cargo.toml` naming the typosquat `proc-macro1` as a dependency
- **Typosquat dropper crate**: `proc-macro1@1.0.107` published 07:11 UTC by compromised account `dtolney` (a typosquat of the legitimate `proc-macro2`, one of the most-used Rust crates in existence - so `proc-macro1` reads as "obviously legit" to a scanner keyed to substrings). The library source of `proc-macro1` is a **genuine copy of proc-macro2 source** so cargo builds still complete cleanly; all malice sits inside `build.rs`. Variant `proc-macro-en` was also seen in the same window
- **Payload behaviour (executed during `cargo build`, not at runtime)**: the malicious `build.rs` reconstructs C2 URLs from base64-encoded fragments, disables TLS verification via a rustls `AcceptAll` verifier, downloads a target-specific binary from `23.254.165.112:9089` under the name `rust-crate_0.1.0` / `_0.2.0` / `_0.3.0` / `_0.4.0` (matched to Linux x86-64, Windows x86-64, macOS x86-64, macOS ARM64), then invokes it with C2 address `23.254.165.112:443` as `argv[1]`. On Unix the binary is dropped to `/tmp/rust-setup` and spawn-detached; on Windows the dropper writes `%TEMP%\rust-setup.ps1` and `rust-setup-launch.vbs`, launches via `wscript.exe` with `CREATE_NO_WINDOW`, and uses `std::mem::forget()` to escape the Cargo build job object so the payload survives after the build finishes
- **Blast radius via transitive dependency chain**: `arrayref` is a foundational primitive used by `blake3`, Rust GUI stacks (`egui`, `eframe`, `iced`, `tiny-skia`, `sctk-adwaita`, `winit`), and Ethereum/Solana components. Wiz observed it in **~35% of environments they scanned, and ~75% of environments where any Rust is present** - so an org that builds any modern Rust code has a high probability of pulling `arrayref` transitively even without a direct `[dependencies]` entry. Any host that ran `cargo build`, `cargo update`, `cargo check`, or CI resolution against these crates between 07:11 and 09:25 UTC on 2026-08-20 executed the payload
- **Attribution**: Wiz reports **significant overlap with DPRK / Lazarus supply-chain campaign infrastructure** (naming and payload patterns previously seen in Famous Chollima / Contagious Interview activity). Both publishing accounts (`droundy` for arrayref, `dtolney` for proc-macro1) appear to have been compromised via credential theft rather than being sock puppets. To create update pressure toward `arrayref@0.3.10`, the attacker also **yanked all prior versions from `0.3.5` to `0.3.9`** so cargo resolvers rolling forward from earlier ranges landed on the malicious version - the Rust Security Response Team subsequently un-yanked those clean releases
- **Detectability**: passive scanners that hash only `arrayref`'s own source code miss this attack completely - the malicious change is a single added line in `Cargo.toml` naming a real-looking dependency, and the payload lives in a separate crate. Detection requires resolving the full dependency graph and flagging previously-unseen crate names, or monitoring `build.rs` execution for outbound HTTP to fresh IPs

## What to do

1. Grep every `Cargo.lock` in your monorepo, on every developer laptop, and in every CI build cache for: `arrayref = "0.3.10"`, `internment = "0.8.7"`, `append-only-vec = "0.1.9"`, or **any version** of `proc-macro1` or `proc-macro-en`. Presence of any of these under the resolved 2026-08-20 07:11-09:25 UTC window is proof the build ran the dropper
2. On any host that resolved (via `cargo build`, `cargo update`, `cargo check`, `cargo test`, or CI) any affected version during that window: **assume the host is compromised**. Rotate every credential the build shell could reach - crates.io API tokens (`~/.cargo/credentials.toml`), npm tokens the same runner also touches, GitHub Actions PATs, cloud provider keys, SSH keys, browser saved logins on developer laptops
3. **Detection artifacts**: look for `/tmp/rust-setup` on Unix (executable, present after the build), `%TEMP%\rust-setup.ps1` and `rust-setup-launch.vbs` on Windows, and outbound connections from the build host to `23.254.165.112:9089` or `23.254.165.112:443`. On a shared CI runner also check for the payload survivor process detached from the cargo job
4. Update to clean versions: `arrayref` <= 0.3.9 (the Rust Security Response Team un-yanked these after the attacker yanked them; they are safe), `internment` <= 0.8.6, `append-only-vec` <= 0.1.8. Do NOT install `proc-macro1` or `proc-macro-en` - both are attacker crates with no legitimate use
5. Add both `proc-macro1` and `proc-macro-en` to any `cargo-deny` deny-list or SBOM alerting policy so future re-publishes under the same slug fire immediately
6. **Systemic hardening**: enable `cargo --frozen` in CI so lockfile changes are explicit; consider `cargo vet` or `cargo crev` for a signed-audit chain against foundational crates; disable arbitrary `build.rs` execution where feasible (harder for GUI/native builds but viable for pure-Rust crates)
7. IOC hashes (SHA-256) for endpoint/AV blocklists: `arrayref-0.3.10` = `25ad700976873c76af785cb99b33c48db7df8b81f21d1e9e06b3676b9a9373ae`; `proc-macro1-1.0.107` = `61198155da51b838772eecf5bfaac6cbc4dcc388dccc56658fc28a8e831b34d4`

## References

- [RUSTSEC advisory-db issue #3161 - arrayref 0.3.10 executes a remote payload at build time via typosquatted proc-macro1](https://github.com/rustsec/advisory-db/issues/3161) - RustSec
- [Supply chain attack on arrayref - Rust Blog (official post-incident writeup by the Rust Security Response Team)](https://blog.rust-lang.org/2026/08/20/supply-chain-attack-on-arrayref/) - Rust Project
- [Popular Rust Crates Compromised in Build-Time Supply Chain Attack - Socket AI Scanner detection](https://socket.dev/blog/popular-rust-crates-compromised) - Socket
- [Rust Supply Chain Attack on arrayref: Significant Overlap with DPRK Campaigns - Wiz threat attribution](https://www.wiz.io/blog/rust-supply-chain-attack-on-arrayref-significant-overlap-with-dprk-campaigns) - Wiz
- [Hackers poison arrayref Rust crate to push infostealer malware - BleepingComputer](https://www.bleepingcomputer.com/news/security/hackers-poison-arrayref-rust-crate-to-push-infostealer-malware/) - BleepingComputer
- [Rust Supply-Chain Attack: arrayref, internment, and append-only-vec Poisoned by the proc-macro1 Build-Time Dropper - StepSecurity](https://www.stepsecurity.io/blog/arrayref-rust-crate-supply-chain-attack) - StepSecurity
- [Rust Supply Chain Attack Puts Build-Time Malware in Crates with 245 Million Downloads - The Hacker News](https://thehackernews.com/2026/08/rust-supply-chain-attack-puts-build.html) - The Hacker News
- [Hackers poison popular Rust crates to steal developers' credentials - The Register](https://www.theregister.com/security/2026/08/21/hackers-poison-popular-rust-crates-to-steal-developers-credentials/5291075) - The Register
- [Two popular Rust crates arrayref and append-only-vec compromised in supply chain attack - Aikido Security](https://www.aikido.dev/blog/two-popular-rust-crates-arrayref-and-append-only-vec-compromised-in-supply-chain-attack) - Aikido
- [Malicious Rust Crate arrayref Runs a Build-Time Payload - SafeDep](https://safedep.io/arrayref-proc-macro1-rust-build-time-malware/) - SafeDep
- [Rust Crates arrayref & append-only-vec Compromised via proc-macro1 - Semgrep](https://semgrep.dev/blog/2026/rust-crates-arrayref-append-only-vec-compromised-proc-macro1/) - Semgrep

---

Canonical page: https://dependencywatch.io/incident/crates-2026-08-20-arrayref-proc-macro1-build-time
Markdown version: https://dependencywatch.io/incident/crates-2026-08-20-arrayref-proc-macro1-build-time.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
