← Back to context

Comment by cedws

3 months ago

Rust makes me especially nervous due to the possibility of compile-time code execution. So a cargo build invocation is all it could take to own you. In Go there is no such possibility by design.

The same applies to any Makefile, the Python script invoked by CMake or pretty much any other scriptable build system. They are all untrusted scripts you download from the internet and run on your computer. Rust build.rs is not really special in that regard.

Maybe go build doesn't allow this but most other language ecosystems share the same weakness.

  • Right, people forget that the xz-utils backdoor happened to a very traditional no-dependencies C project.

    • xz-utils has a ton of build dependencies. The backdoor implant exploited a flaw in an m4 macro build dep.

You're confusing compile-time with build-time. And build time code execution exists absolutely exists in go, because that's what a build tool is. https://pkg.go.dev/cmd/go#hdr-Add_dependencies_to_current_mo...

  • I think you're misunderstanding.

    "go build" of arbitrary attacker controlled go code will not lead to arbitrary code execution.

    If you do "git clone attacker-repo && cargo build", that executes "build.rs" which can exec any command.

    If you do "git clone attacker-repo && go build", that will not execute any attacker controlled commands, and if it does it'll get a CVE.

    You can see this by the following CVEs:

    https://pkg.go.dev/vuln/GO-2023-2095

    https://pkg.go.dev/vuln/GO-2023-1842

    In cargo, "cargo build" running arbitrary code is working as intended. In go, both "go get" and "go build" running arbitrary code is considered a CVE.

    • But `go generate` can, and that is required to build some go projects.

      It is also somewhat common for some complicated projects to require running a Makefile or similar in order to build, because of dependencies on things other than go code.

      2 replies →

  • I don't really get what you're trying to say, go get does not execute arbitrary code.

Does it really matter, though? Presumably if you're building something is so you can run it. Who cares if the build script is itself going to execute code if the final product that you're going to execute?

  • With a scripting language it can matter: If I install some package I can review after the install before running or run in a container or other somewhat protected ground. Whereas anything running during install can hide all trades.

    Of course this assumption breaks with native modules and with the sheer amount of code being pulled in indirectly ...

Build script isn't a big issue for Rust because there is a simple mitigation that's possible. Do the build in a secure sandbox. Only execution and network access must be allowed - preferably as separate steps. Network access can be restricted to only downloading dependencies. Everything else, including access to the main filesystem should be denied.

Runtime malicious code is a different matter. Rust has a security workgroup and their tools to address this. But it still worries me.