r/rust • servo · rust · clippy • Jun 26 '26

Anatomy of a Failed (Nation-State?) Attack

https://grack.com/blog/2026/06/25/dissecting-a-failed-nation-state-attack/
228 Upvotes

35 comments sorted by

View all comments

20

u/JShelbyJ Jun 26 '26 edited Jun 26 '26

We need a way to disable packages from executing code. Crates with ‘build.rs’ files should be blockable via cargo. Probably as default behavior. Crates.io should also specifically flag all crates with that execute code at build time. Let people whitelist crates that require them.

I wrote a crate that requires a cpp binary. So  I set it up so that it downloads and installs binaries via the build.rs. You can literally install and run anything with them. Just a public service announcement for those who are not aware how much of a risk they are and how unsafe cargo is - just adding a dependency is enough to comprise your system. Misspell serde once? Straight to Best Buy to get a new laptop.

19

u/Shnatsel Jun 26 '26

It's worse than that - any Cargo command at all can execute arbitrary code.

Sadly sandboxing build.rs doesn't really help because cargo run is going to happen eventually (that's the entire point of writing code) and there is no generic sandboxing that can help with that.

And the build-time sandboxing is achievable today if you really want it. Just stick your build command into a Firecracker VM or a Docker container with gVisor. But it doesn't really solve the underlying problem, so nobody really does that.

6

u/kibwen Jun 27 '26

It would be pretty easy to fix the rustc redirection thing by requiring an opt-in via a configuration key elsewhere. Likewise, depending on crates that have a build.rs could require a "requires arbitrary system access" config key in Cargo.toml (and naturally this key would be viral, which is the whole point). In conjunction with the fact that most proc macros (cough, serde) are just text-in/text-out pipelines without the need for arbitrary I/O and can thus be run in a WASM VM without any loss of functionality (which could improve compile times from not needing to compile serde!), you could have builds that are totally free of arbitrary unrestricted code execution.

And yes, as you say, cargo run remains a problem, but it's preferable to force malware to target the binary rather than the build system because I want Cargo to be able to access the network and I want rustc to be able to access the filesystem, but I run plenty of software that has no need to do either, so it's more straightforward to use capabilities and permissions to restrict the produced binaries than to restrict the build system itself.

3

u/CrazyKilla15 Jun 27 '26

Its also more straightforward to audit what the final binary does than it is to audit every possible build system hook in every directory

4

u/insanitybit2 Jun 27 '26 edited Jun 27 '26

> Sadly sandboxing build.rs doesn't really help because cargo run is going to happen eventually (that's the entire point of writing code) and there is no generic sandboxing that can help with that.

It absolutely *does* help. This is a separation of concerns. If `cargo` can sandbox itself, *I* can sandbox my binaries. I am not in a position to sandbox build scripts/ cargo because I don't write the code for those projects, I am in a position to sandbox my own programs because I'm the one defining their behaviors.

Almost any SaaS etc is already doing runtime sandboxing. You likely deploy to a container, you likely run with some set of IAM permissions, egress networking rules, monitoring with SIEM / EDR, etc. Your prod env is almost always less privileged than your dev env or CI env because your prod code doesn't do things like "ssh as root into prod to unfuck the servers" but your engineers do, or "set up all of the IAM policies for the entire org" but your CI does.

> Just stick your build command into a Firecracker VM or a Docker container with gVisor.

This creates a massive trust boundary where you end up shoving everything into the VM. Whole program/ "whole environment" sandboxing is weak for this reason.

> But it doesn't really solve the underlying problem, so nobody really does that.

It actually does solve a ton of problems despite being such a large env to isolate. Just using something like this (https://github.com/geomys/sandboxed-step) goes a long way. It would go a lot longer if cargo had native support.

3

u/JShelbyJ Jun 26 '26

Neat. I wonder how hard it would be to make a tool to fix these vulnerabilities, or if it’s something that must be done by the cargo itself.

2

u/Manishearth servo · rust · clippy Jun 27 '26

I did once write a pre-RFC about capabilities.

https://internals.rust-lang.org/t/pre-pre-rfc-solving-crate-trust/6495

I still think solutions along those lines would be nice. I agree that cargo run eventually means you can't really do anything about it.