# arrayref: a Poisoned Rust Crate Hits the AI Build Endpoint
> The DPRK crew behind the Mastra AI-framework attack poisoned arrayref so its build script runs a credential stealer during cargo build, on the developer or CI endpoint that builds your AI tooling, not on your inference nodes.
- **Publisher:** Optimus Labs · Civilizations
- **Published:** 2026-08-20
- **Severity:** CRITICAL · SUPPLY CHAIN
- **Types:** Supply chain, Coding agent
- **Categories:** SC — Supply Chain nth Party Risk; AI — AI Asset Supply Chain Security; AL — Agentware Lifecycle Security; CH — Cyber Hygiene
- **Vendors / products affected:** crates.io, RustSec, Wiz, StepSecurity, Semgrep
- **Blast radius:** Every developer laptop and CI runner that compiled arrayref 0.3.10, internment 0.8.7 or append-only-vec 0.1.9, directly or transitively, ran attacker code at compile time. arrayref carries ~245M all-time downloads and Wiz places it in roughly three quarters of Rust environments. The malicious versions were live about 86 minutes and RUSTSEC-2026-0260 states there is no evidence of actual usage. Real downstream reach is GUI (winit, egui, eframe, iced via tiny-skia), crypto/hashing (blake2b_simd, blake2s_simd, older blake3) and blockchain (Ethereum, Solana). No AI/ML framework is a named victim: candle, tokenizers, safetensors and qdrant-client do not depend on arrayref, and pure-Python stacks are not directly hit.
- **Canonical URL:** https://www.optimuslabs.io/research/briefings/arrayref-rust-crate-build-time-rce
## Summary

A compromised maintainer account (droundy), alongside an impersonation account (dtolney, mimicking dtolnay) published malicious arrayref 0.3.10, internment 0.8.7 and append-only-vec 0.1.9 to crates.io. Each added a typosquatted dependency, proc-macro1 (mimicking proc-macro2), whose build.rs downloads and executes a stage-2 implant during compilation. Merely building an affected project, locally, in CI, or through an AI coding agent, executes it. This is not a model backdoor. The payload runs at compile time, so the target is the machine that builds AI tooling and the value to the actor is that host's credential store.

## What happened

- 01:17 UTC: a fake GitHub account is created. 07:15: malicious arrayref 0.3.10 goes live on crates.io. 07:54: reported to RustSec. 08:03: proc-macro1 deleted. 08:41: arrayref pulled. Total exposure window roughly 86 minutes.
- arrayref 0.3.10, internment 0.8.7 and append-only-vec 0.1.9 each added the typosquatted dependency proc-macro1. Its build.rs fetches and runs a stage-2 implant during `cargo build`, so compilation alone is execution.
- Confirmed payload behavior (Wiz, StepSecurity, BleepingComputer): a cross-platform stealer/backdoor for Linux, Windows and macOS on x86_64 and aarch64. It reads Chrome, Brave and Edge saved logins from their SQLite Login Data databases and collects host credentials.
- It persists through Registry Run keys, LaunchAgents or systemd, and beacons to C2 over HTTPS at path /49890878, with a DGA fallback of 10 .com domains every 5 days.
- Attribution is strong overlap, not vendor-confirmed here. Wiz reports the C2 path /49890878 matches the Mastra AI-agent-framework campaign that Microsoft attributed to DPRK / Sapphire Sleet, a victim-reported IP appears in Mandiant/Google analysis of UNC1069's axios npm attack, and both campaigns use the Hostwinds 23.254.164.0/23 range.

## Why it matters

- Every build runs on an endpoint. The stealer executes, persists and beacons from a developer laptop or CI runner, never from an inference node, so the exposure is an endpoint problem rather than a model-serving one.
- AI teams build a lot of Rust: tokenizers, serving and inference layers, checkpoint-hashing crypto, data-pipeline and CLI tooling, dashboards. A poisoned transitive crate therefore detonates on exactly the machines that hold AI secrets.
- The endpoint blind spot: a lockfile scan flags the crate. Only the endpoint shows that a build actually ran it, what it stole, and whether it persisted.
- Nobody installs arrayref on purpose. It arrives transitively, which is why a foundational crate with ~245M downloads is a better lever for this actor than any AI framework.
- There is no patched release. Remediation is a downgrade, which makes lockfile hygiene and build provenance the durable controls rather than a version bump.

## What to do

- Grep every Cargo.lock, CI job and container image for arrayref 0.3.10, internment 0.8.7, append-only-vec 0.1.9 and any proc-macro1.
- There is no patched release. Downgrade and pin arrayref at or below 0.3.9, internment at or below 0.8.6, append-only-vec at or below 0.1.8, then rebuild clean.
- Treat any dev laptop or CI runner that built a malicious version as breached: rotate its credentials, check persistence, and reimage rather than clean in place.
- Separate build from runtime so inference nodes never run cargo build, sandbox build.rs, scope CI tokens, and run cargo-audit and cargo-deny in CI.
- Put endpoint detection on build machines. Dev laptops and CI runners are production endpoints, and lockfile scanning cannot see execution, persistence or exfiltration.

## Remediation

### Contain now (0-24h)

- Grep every Cargo.lock, CI job and container image for arrayref 0.3.10, internment 0.8.7, append-only-vec 0.1.9 and any proc-macro1 or proc-macro-en.
- Hunt the IoCs: /tmp/rust-setup on Unix, %TEMP%\rust-setup.ps1 and %TEMP%\rust-setup-launch.vbs on Windows, egress to 23.254.165[.]112:9089 and :443, secondary 23.254.167[.]107:443, hwsrv-798836.hostwindsdns[.]com, C2 path /49890878.
- On build endpoints, watch process lineage: cargo or rustc spawning curl, powershell or wscript, and writes to /tmp/rust-setup.
- No patched release exists (RUSTSEC-2026-0260). Downgrade and pin arrayref at or below 0.3.9, internment at or below 0.8.6, append-only-vec at or below 0.1.8, then rebuild clean.

### Investigate, assume breach (24-72h)

- Rotate cloud and model-registry tokens first (AWS, GCP, Azure, S3, GCS, HF Hub): they unlock models, checkpoints and data.
- Then rotate Hugging Face and Weights & Biases keys, crates.io and npm publishing tokens, and code-signing keys, because those enable the next poisoning.
- Then rotate GitHub and GitLab PATs, CI/CD secrets, vector-DB and LLM-provider keys, SSH keys, and invalidate browser sessions.
- Check persistence (Registry Run keys, LaunchAgents, systemd) and review egress since 07:15 UTC on Aug 20.
- Reimage any dev or CI endpoint that built a malicious version. Do not clean in place: this is a full backdoor with persistence.

### Harden strategically

- Put endpoint detection on build machines: lockfile scanning cannot see execution, persistence or exfiltration, only the endpoint can.
- Separate build from runtime so inference nodes never run cargo build, and sandbox build.rs, which executes arbitrary code at compile time.
- Scope CI secrets so build jobs cannot reach production model-deploy keys.
- Commit Cargo.lock, run cargo-audit and cargo-deny in CI, watch RustSec alongside PyPI and npm, and require build provenance or attestation.

## Leaked by association

- Cloud consoles: AWS / GCP / Azure
- Model registry: S3 / GCS / HF Hub
- Publishing tokens: crates.io / npm
- Source control: GitHub / GitLab PAT
- CI/CD secrets: Actions / GitLab CI
- Hugging Face: HF_TOKEN
- Weights & Biases: WANDB_API_KEY
- LLM provider keys: OpenAI / Anthropic
- Vector DB: Qdrant / Pinecone
- SSH keys: ~/.ssh/id_*

Rotate cloud and model-registry credentials first: they unlock the models, checkpoints and data themselves. Publishing tokens for crates.io and npm come next, because they let this actor poison your next build.

Browser-saved logins in Chrome, Brave and Edge are the confirmed theft vector. The rest is what a dev or CI endpoint holds. The ordering is blast-radius priority for an AI org, not measured per-victim theft.

## Indicators of compromise

- Malicious versions: arrayref 0.3.10, internment 0.8.7, append-only-vec 0.1.9, proc-macro1 (all versions)
- Deleted crates: proc-macro-en, aovine, arone, aronenao, tinymember
- Accounts: droundy (compromised maintainer), dtolney (impersonating dtolnay)
- Files: /tmp/rust-setup, %TEMP%\rust-setup.ps1, %TEMP%\rust-setup-launch.vbs
- Network: 23.254.165[.]112:9089 and :443, 23.254.167[.]107:443, hwsrv-798836.hostwindsdns[.]com
- C2 path: /49890878 (shared with the Mastra campaign)
- Advisory: RUSTSEC-2026-0260 (no patched release, downgrade only)

## Sample output

```
# Find affected versions anywhere they are pinned
rg -n "arrayref 0.3.10|internment 0.8.7|append-only-vec 0.1.9|proc-macro1" Cargo.lock

# Build-endpoint IoCs
ls -la /tmp/rust-setup 2>/dev/null
grep -R "23.254.165" /var/log 2>/dev/null
```

## Sources

- [RUSTSEC-2026-0260 — canonical advisory](https://rustsec.org/advisories/RUSTSEC-2026-0260.html)
- [StepSecurity — build-time chain analysis](https://www.stepsecurity.io/blog/arrayref-rust-crate-supply-chain-attack)
- Wiz — attribution and Rust-environment reach (URL pending)
- BleepingComputer — reporting, 245M downloads (URL pending)
- Semgrep — IoCs, SHA-256 payloads, detection rules (URL pending)
- Microsoft Security — Mastra npm compromise, Sapphire Sleet (URL pending)
- Socket, The Hacker News (blake3 dropped arrayref in 1.8.7), Aikido — corroboration (URL pending)

---

Published by Optimus Labs · Civilizations, the threat research team at Optimus Labs. Optimus Labs secures the enterprise agentic AI attack surface: discovery and governance of every AI agent, MCP server, and skill, posture management against the OWASP Top 10 for Agentic Applications, and runtime behavior anomaly detection. More briefings: https://www.optimuslabs.io/research/briefings
