Skip to main content
Backdoored Rust Packages on Crates.ioIncident
4 min readFor Security Engineers

Backdoored Rust Packages on Crates.io

On August 20, malicious versions of three Rust packages appeared on crates.io. These packages contained backdoors that executed during the build process, before your code ever ran. One of the compromised packages, arrayref, has 245 million all-time downloads and 53.7 million downloads in the last 90 days. Wiz researchers linked the attack to North Korean threat actors.

This wasn't a runtime exploit. Your dependency scanner wouldn't catch it. Your container security tool wouldn't flag it. The malicious code ran when cargo build compiled your project.

Timeline

August 20: Three malicious Rust packages were published to crates.io with backdoors in build scripts.

Initial detection: RustSec received the first report. The packages were live and being downloaded.

Attribution: Wiz analysis connected the attack pattern and infrastructure to North Korean threat actors.

The exact detection-to-removal window isn't public, but every hour mattered. Arrayref's download velocity means thousands of builds potentially executed the backdoor before the packages were removed.

Which Controls Failed

No build-time sandboxing. Cargo build scripts run with the same permissions as your user account. They can read SSH keys, write to .bashrc, exfiltrate environment variables, or install persistent backdoors. The Rust ecosystem treats build scripts as trusted code.

Insufficient package vetting. Crates.io allows anyone to publish packages. There's no pre-publication security review, no mandatory code signing, and no verification that the publisher owns the namespace they're claiming. The malicious packages appeared legitimate until someone looked at the build scripts.

Missing dependency pinning. If your Cargo.toml specified arrayref = "0.3" without a patch version, you automatically pulled the compromised version on your next build. Your CI pipeline didn't ask permission.

No build script auditing. Most teams review application code but skip build scripts. The backdoor sat in plain sight in build.rs files, but automated tools don't flag "suspicious" build behavior because legitimate packages do complex things at build time.

What Standards Require

NIST 800-53 Rev 5 requires supply chain risk management in SA-12: "Employ [Assignment: organization-defined controls] to protect against supply chain threats." Build-time backdoors are explicitly a supply chain threat. The control expects you to assess and monitor third-party components, including their build processes.

PCI DSS v4.0.1 Requirement 6.3.2 states: "An inventory of bespoke and custom software, and third-party software components incorporated into bespoke and custom software is maintained to facilitate vulnerability and patch management." Your dependency manifest isn't enough. You need to know what those dependencies do at build time, not just runtime.

ISO/IEC 27001:2022 Control A.5.19 addresses information security in supplier relationships. If you're pulling code from crates.io, those package maintainers are suppliers. The control requires you to "define and agree on information security requirements relevant to the relationship with the supplier." Build script permissions fall under this requirement.

SOC 2 Type II CC7.2 (Common Criteria 7.2) addresses system monitoring: "The entity monitors system components and the operation of those components for anomalies that are indicative of malicious acts, natural disasters, and errors." A build script that phones home or writes to unexpected filesystem locations is an anomaly your monitoring should catch.

None of these standards say "don't use open source." They say: know what you're running, limit what it can do, and watch for unexpected behavior.

Lessons and Action Items

Pin your dependencies to exact versions. Change arrayref = "0.3" to arrayref = "0.3.8" in your Cargo.toml. Use Cargo.lock in version control for reproducible builds. This doesn't prevent the initial compromise, but it stops automatic propagation.

Audit build scripts before adding dependencies. When you add a new crate, read its build.rs. If it shells out, makes network calls, or writes outside OUT_DIR, ask why. Create a checklist: Does this build script need network access? Does it need to write to my home directory? If not, it's suspect.

Sandbox your build environment. Run builds in containers with restricted network access and read-only mounts for sensitive directories. Use --network=none in Docker builds when possible. If a build script tries to exfiltrate your AWS credentials, it should fail because those credentials aren't mounted.

Monitor build behavior. Log what your builds do. If cargo build suddenly makes HTTPS requests to unfamiliar domains, your SIEM should alert. If it writes to .ssh/, that's not normal build behavior. Tools like strace or osquery can track this, but you need baselines first.

Implement dependency review gates. Before a developer adds a new dependency, require a second person to review the package's build scripts, recent commits, and maintainer history. This slows down development by hours, not days, but catches obvious backdoors.

Use software composition analysis (SCA) tools that understand build scripts. Most SCA tools check for known CVEs in dependencies. You need tools that parse build scripts for suspicious patterns: network calls, filesystem writes outside the build directory, shell command execution with user-controlled input.

Subscribe to security advisories. RustSec publishes advisories for the Rust ecosystem. Set up alerts. When arrayref gets flagged, you need to know within minutes, not days.

Run builds in ephemeral environments. Your CI runners should start clean for every build and get destroyed afterward. If a backdoor installs a cronjob, it dies with the container. This doesn't prevent the initial compromise, but it limits persistence.

The North Korean attribution matters because it signals intent. This wasn't a researcher proving a point or a script kiddie causing chaos. State-sponsored actors targeting build systems are looking for persistence in developer environments and access to production secrets. They're patient.

Your build process is part of your attack surface. Treat it that way.

Topics:Incident

You Might Also Like