# arrayref and proc-macro1 teardown: a crates.io typosquat

> How a likely compromised account added the typosquat proc-macro1 to arrayref and two other crates, what its build.rs ran, and whether Chainsaw stops it.

Source: https://chain305.com/teardowns/proc-macro1-crates-typosquat/

---

# Teardown: the arrayref and proc-macro1 crates.io attack

One lookalike dependency, three popular crates, malware at compile time.

What happened on 20 August 2026, how a copy of proc-macro2 got into arrayref's dependency tree, and where Chainsaw would stop it.

By [Muhammad Zeeshan Sultan](https://chain305.com/about/#founder), founder of Chain305 · October 2026

Questions and answers

## What happened?

The proc-macro1 attack is a crates.io typosquat from 20 August 2026, in which malicious versions of three Rust crates went up from one maintainer’s account: `arrayref 0.3.10` at 07:15 UTC, `internment 0.8.7` at 07:34 and `append-only-vec 0.1.9` at 07:37. Each version added a dependency on `proc-macro1`, a lookalike of the widely used `proc-macro2`, whose `build.rs` downloaded and started a platform-specific payload while Cargo compiled the project. The Rust Security Response Team, alerted by the Nextron Systems research team, deleted the three versions within 86, 90 and 107 minutes. `arrayref 0.3.10` was downloaded 2,285 times before removal, which RustSec puts at under 10% of `arrayref` download traffic.

## How did the malicious crate get in?

Through a dependency line, not a mistyped name. Nobody had to type `proc-macro1`: the attacker published new versions of crates people already used and listed it as a dependency. The Rust blog says the team does not believe the maintainer acted maliciously and that their computer or credentials were “likely compromised”. It does not say how.

The lookalike was built to pass a quick look. JFrog found that `proc-macro1 1.0.107` is a renamed copy of the real `proc-macro2 1.0.107`, with its author field faked as David Tolnay, who maintains the real crate. The additions are a build script and three build dependencies the real crate does not need: `ureq`, `rustls` and `base64`.

Earlier `arrayref` releases had been yanked; the Rust team unyanked them. RustSec says the 2,285 downloads were under 10% of `arrayref` download traffic, because most users had older versions locked.

## What ran at build time?

A download-and-execute step in `proc-macro1`’s `build.rs`. Cargo runs a build script while compiling, before any of the crate’s code is called, so building a project that resolved the malicious version was enough. According to JFrog’s analysis:

-   **It rebuilt its download URL from Base64 fragments** at runtime, pointing at `23[.]254[.]165[.]112` on port 9089.
-   **It picked a payload by platform:** separate binaries for Linux x86\_64, Windows x86\_64, macOS x86\_64 and macOS on Apple silicon.
-   **It turned off TLS certificate checks** for the download.
-   **On Linux and macOS** it wrote the payload to `/tmp/rust-setup`, made it executable and started it detached, with `23[.]254[.]165[.]112:443` as an argument.
-   **On Windows** it wrote `%TEMP%\rust-setup.ps1` and a `rust-setup-launch.vbs` launcher, and ran the script hidden through `wscript` and PowerShell with the execution policy bypassed.

JFrog could not retrieve the second stage, because the server had stopped answering, so what it did next is unknown. JFrog’s advice is to treat any machine where the script ran as fully compromised.

## Would Chainsaw have stopped it?

Yes, on day 0, for builds that go through the Chainsaw proxy. This comes from our re-run of 58 attacks from 2026 against production Chainsaw (v0.22.118) on 19 October 2026:

-   **The typosquat rule refuses `proc-macro1` on day 0.** `proc-macro1 1.0.107` is refused on its first download by the default rule that blocks suspected typosquats.
-   **Its build script trips a second rule.** The `build.rs` network connection also trips the default rule on install scripts that fetch remote URLs.
-   **Either refusal fails the build of `arrayref`, `internment` and `append-only-vec`.** Cargo cannot fetch `proc-macro1`, so its build script never runs.
-   **Builds that bypass the proxy get the malware.** A laptop or CI runner pointed straight at crates.io is not protected. That is why Chainsaw also gates CI, pins laptops through MDM and blocks direct registry traffic at the network.

How the typosquat matching works is covered in [our guide to typosquatting](https://chain305.com/learn/typosquatting/). Every attack in the re-run is on the [2026 attack coverage page](https://chain305.com/attack-coverage-2026/).

## What should you do?

The proc-macro1 typosquat reached builds through `arrayref 0.3.10`, `internment 0.8.7` and `append-only-vec 0.1.9`. The most urgent step, per JFrog, is to treat any machine or runner that built one of the three as compromised. To check with Cargo, run `cargo tree -i proc-macro1` in each workspace, and search `Cargo.lock` and any vendored crates for these versions:

-   `arrayref 0.3.10` (last clean release `0.3.9`)
-   `internment 0.8.7` (last clean release `0.8.6`)
-   `append-only-vec 0.1.9` as published on 20 August 2026 (crates.io now serves a clean `0.1.9` the maintainer published on 18 October 2026, and `0.1.10`)
-   `proc-macro1`, any version

`cargo tree` only reads the current lockfile, so also look in the local registry cache, as the Rust blog suggests: search `~/.cargo/registry/cache` for `.crate` files with the names and versions above, on every developer machine and CI runner which built Rust code on 20 August 2026.

If you find one, follow JFrog’s advice:

1.  **Treat the machine or runner as compromised.** The second stage is unknown, so cleaning up the visible files is not enough.
2.  **Rotate every credential the build could reach:** registry tokens, cloud keys, SSH keys and CI secrets on the machine.
3.  **Look for the dropped files:** `/tmp/rust-setup`, `%TEMP%\rust-setup.ps1` and `%TEMP%\rust-setup-launch.vbs`.
4.  **Block `23[.]254[.]165[.]112`** on ports 9089 and 443.
5.  **Move to a clean release** (`arrayref 0.3.9`, `internment 0.8.6`, `append-only-vec 0.1.8` or the October `0.1.9` and later) and regenerate the lockfile from crates.io.

For the next one, keep `Cargo.lock` committed and review every change to the lockfile. A new crate appearing in the tree, with a name one character away from a popular one, is the signal the proc-macro1 attack left.

## Sources

-   Rust Blog, [Supply chain attack on arrayref](https://blog.rust-lang.org/2026/08/20/supply-chain-attack-on-arrayref), 20 August 2026.
-   RustSec, [RUSTSEC-2026-0260: arrayref](https://rustsec.org/advisories/RUSTSEC-2026-0260.html), [RUSTSEC-2026-0266: internment](https://rustsec.org/advisories/RUSTSEC-2026-0266.html), [RUSTSEC-2026-0262: append-only-vec](https://rustsec.org/advisories/RUSTSEC-2026-0262.html) and [RUSTSEC-2026-0265: proc-macro1](https://rustsec.org/advisories/RUSTSEC-2026-0265.html).
-   crates.io, [append-only-vec versions](https://crates.io/crates/append-only-vec/versions).
-   JFrog Security Research, [Compromised Rust crates on crates.io silently execute malware at build time](https://research.jfrog.com/post/arrayref-proc-macro1-crates-io/), August 2026.

One teardown per notable attack

## Get the next teardown by email

What happened, the install-path angle most coverage misses, and the rule that refuses it.

[Subscribe to teardowns](https://chain305.com/teardowns/) [Read what a package firewall catches →](https://chain305.com/what-is-a-package-firewall/)
