Remix.run Logo
cedws 6 days 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.

exDM69 5 days ago | parent | next [-]

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.

pdw 5 days ago | parent | next [-]

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

theteapot 5 days ago | parent [-]

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

cedws 5 days ago | parent | prev | next [-]

Yes but it's the fact that cargo can pull a massive unreviewed dependency tree and then immediately execute code from those dependencies that's the problem. If you have a repo with a Makefile you have the opportunity to review it first at least.

duped 5 days ago | parent | next [-]

Do you review the 10k+ lines of generated bash in ./configure, too?

cozzyd 5 days ago | parent [-]

./configure shouldn't be in your repo unless it's handwritten

johnisgood 5 days ago | parent [-]

Pretty much. It is called "autotools" for a reason.

Theoretically you should be able to generate the configuration scripts through "autoconf" (or autoreconf), or generate Makefile.in for configure from Makefile.am using "automake", etc.

pharrington 5 days ago | parent | prev [-]

You are allowed to read Cargo.toml.

cedws 5 days ago | parent [-]

Cargo.toml does not contain the source code of dependencies nor transient dependencies.

magackame 5 days ago | parent [-]

Welp, `cargo tree`, 100 nights and 100 coffees then it is

marshray 5 days ago | parent | next [-]

Yes!

I sometimes set up a script that runs several variations on 'cargo tree', as well as collects various stats on output binary sizes, lines of code, licenses, etc.

The output is written to a .txt file that gets checked-in. This allows me to easily observe the 'weight' of adding any new feature or dependency, and to keep an eye on the creep over time as the project evolves.

johnisgood 5 days ago | parent | prev [-]

You will need something stronger than caffeine.

Bridged7756 5 days ago | parent | prev [-]

In JavaScript just the npm install can fuck things up. Pre-install scripts can run malicious code.

pharrington 5 days ago | parent | prev | next [-]

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...

TheDong 5 days ago | parent | next [-]

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.

thayne 5 days ago | parent [-]

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.

TheDong 5 days ago | parent [-]

The culture around "go generate" is that you check in any files it generates that are needed to build.

In fact, for go libraries you effectively have to otherwise `go get` wouldn't work correctly (since there's no way to easily run `go generate` for a third-party library now that we're using go modules, not gopath).

Have you actually seen this in the wild for any library you might `go get`? Can you link any examples?

thayne 5 days ago | parent [-]

> Have you actually seen this in the wild for any library you might `go get`?

Not for a library, but I have for an executable. Unfortunately, I don't remember what it was.

cedws 5 days ago | parent | prev [-]

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

fluoridation 5 days ago | parent | prev | next [-]

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?

johannes1234321 5 days ago | parent [-]

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 ...

goku12 5 days ago | parent | prev [-]

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.