A Fake Rust Maintainer Poisoned 3 Crates, Then Ran Code at Compile Time

By hirantha.me Newsroom (AI-generated)4 min read

An impersonated crates.io account slipped a typosquatted dependency into arrayref, internment and append-only-vec, running attacker code during cargo build.

Image: The Hacker News
On this page

What happened

On August 20, 2026, someone impersonating Rust developer David Tolnay created a lookalike crates.io account and used it to publish a fake package called proc-macro1 - a typosquat of the ubiquitous proc-macro2 crate. Two hours later, three real, widely used crates started shipping updates that quietly added proc-macro1 as a dependency: arrayref 0.3.10, internment 0.8.7, and append-only-vec 0.1.9.

Those three crates were not compromised through a stolen release process or a hijacked CI (continuous integration) pipeline. The attacker had taken over the crates.io account of arrayref's actual maintainer, David Roundy, who has held it since 2009. The Rust Security Response Team said afterward that it does not believe Roundy acted maliciously - his computer or credentials were almost certainly compromised separately.

Why a dependency bump was enough

Adding a single line to a Cargo.toml file was all it took, because proc-macro1 carried a build.rs script. Build scripts in Rust run automatically during cargo build, cargo check, or cargo test, before any of the project's actual code executes and before most static analysis tools would ever look at it. Developers who simply compiled a project depending on one of the three crates ran the attacker's code without ever importing or calling anything from it.

That script reassembled a payload server address from base64 fragments, disabled TLS (Transport Layer Security) certificate validation so it could fetch a binary anyway, and downloaded a platform-specific payload: a PowerShell and VBS (Visual Basic Script) file pair on Windows, a Unix binary written to /tmp/rust-setup on Linux and macOS. On Linux, the payload dropped itself into folders disguised with names like AzureKits and ServiceKit, installed a systemd service to survive reboots, and used Rust's std::mem::forget to detach its own process so it kept running after the build finished.

How fast it moved, and how fast it was caught

The timeline, all in UTC (Coordinated Universal Time) on August 20:

  • 01:17-01:26 - impersonator accounts created on GitHub and crates.io
  • 01:55 - a clean decoy version of proc-macro1 published, presumably to look established
  • 07:11 - the weaponized proc-macro1 version published
  • 07:15 - malicious arrayref 0.3.10 published; the attacker yanked the prior safe versions (0.3.5 through 0.3.9) within 40 seconds, pushing anyone updating toward the poisoned release
  • 07:34-07:37 - malicious internment 0.8.7 and append-only-vec 0.1.9 published
  • 07:54 - a researcher identified as jhobern reported the pattern to the Rust Security Response Team, 39 minutes after the arrayref publish
  • 08:03-09:25 - the team verified the reports and deleted every malicious version

Each package was live for a different stretch before deletion: 86 minutes for arrayref, 90 for internment, 107 for append-only-vec. Security firm Nextron Systems is credited with independently flagging the same activity around the same time.

The blast radius

arrayref alone has been downloaded roughly 245 million times over its lifetime, with about 54 million of those in the 90 days before the attack, according to the security research firm StepSecurity, which counted 406 other crates depending on it directly. Across all three compromised packages, StepSecurity put combined lifetime downloads at around 264 million. Projects sitting downstream of arrayref include the image library tiny-skia, the windowing library winit, the GUI (graphical user interface) toolkit egui, the cryptographic hash library blake3, Solana's spl-token, and Ethereum tooling built on revm-precompile - none of which were themselves compromised, but all of which pull in arrayref as a transitive dependency and would have run the malicious build script on any fresh compile during the exposure window.

No CVE (Common Vulnerabilities and Exposures identifier) has been assigned to the incident. It is tracked instead as a RustSec advisory, RUSTSEC-2026-0260.

The response

The Rust Security Response Team locked the impersonator's accounts, deleted every malicious crate version, and reversed the yanks the attacker had placed on the legitimate older releases. It also locked Roundy's actual account as a precaution while treating him as a victim rather than a suspect, writing that it did not believe he had acted maliciously.

Security researchers noted that the attack's network infrastructure overlapped with servers previously linked to North Korea-associated supply chain campaigns, including past compromises of the npm packages in the Mastra ecosystem and of the axios library. No security vendor has formally attributed this specific incident to a named group.

What this means in practice

If you have arrayref, internment, or append-only-vec anywhere in a Cargo.lock file, check whether any build between 07:00 and 09:30 UTC on August 20, 2026 pulled the affected versions - arrayref 0.3.10, internment 0.8.7, or append-only-vec 0.1.9 - and treat any machine that ran one as potentially compromised, not just the dependency tree. Pin to the last known-good versions (0.3.9, 0.8.6, and 0.1.8 respectively) until you've confirmed your lockfile never touched the bad releases. More broadly, this is a reminder that Rust's build.rs mechanism runs with full permissions before any of your own review process - code signing, CI approval gates, even careful Cargo.toml diffs - gets a chance to catch it. Enabling two-factor authentication on any crates.io publishing account you maintain, and auditing dependency updates for newly added crates rather than just version bumps of existing ones, would have surfaced this one.

Sources

  • The Hacker News
  • StepSecurity
  • warp2search.net
  • rust
  • supply-chain-attack
  • crates.io
  • open-source-security
  • malware

Frequently asked questions

Am I affected if I use arrayref, internment, or append-only-vec?

Only if your build pulled arrayref 0.3.10, internment 0.8.7, or append-only-vec 0.1.9 between roughly 07:00 and 09:30 UTC on August 20, 2026. Check your Cargo.lock history and pin to the last safe versions, 0.3.9, 0.8.6, and 0.1.8, until you confirm this.

Do I need to update or remove code from my project?

No code changes are needed in your own project. The risk was that the build script ran arbitrary code on the machine compiling it, so the response is to check and clean affected build machines, not your source tree.

Why didn't a security scanner catch this before the build ran?

The malicious code lived in a build.rs script, which Cargo executes automatically at compile time before any application code runs or gets analyzed, so standard static analysis of the published crate's public API would not have flagged it.

Was the maintainer of arrayref responsible for this?

No. The Rust Security Response Team said it does not believe David Roundy, arrayref's longtime maintainer, acted maliciously, and instead assessed that his account or machine was compromised by a separate attacker.

Is this linked to a known hacking group?

Researchers noted the attack's server infrastructure overlapped with past North Korea-linked supply chain incidents, including the Mastra npm compromise and the axios compromise, but no security vendor has formally attributed this attack to a specific named group.

Sources & credits

  1. Rust Supply Chain Attack Puts Build-Time Malware in Crates with 245 Million Downloads - The Hacker News
  2. Rust Supply-Chain Attack: arrayref, internment, and append-only-vec Poisoned by the proc-macro1 Build-Time Dropper - StepSecurity
  3. Rust Supply Chain Attack: Malicious arrayref Crate Pulled After 2-Hour Breach - warp2search.net

The sources the AI writer says it used.

More in Cybersecurity

View all Cybersecurity posts