Live data from Hacker News

Malicious Rust crate Arrayref runs a build-time payload

safedep.io

351–360 of 529 posts

Re: Malicious Rust crate Arrayref runs a build-time payload

#351

Earlier quoted context omitted.

People confuse what they want. They do not want a big stdlib. The downsides are real (the stdlib cannot make breaking changes), and there are no upsides (except, maybe, for faster compilation, since std comes precompiled). They want more official crates (e.g. `regex` and `libc` are official crates, maintained by the Rust project). And the Rust project does not oppose to that, it just doesn't have the funding.

> there are no upsides (except, maybe, for faster compilation Another big reason to put something in std is providing types for cross-crate compatibility. If I want to pass a String from one crate to another, I’m glad that string is defined in std so there’s an obvious type we can both use in our APIs. C - for example - does not have this luxury. Everyone makes their own string type, and C APIs all need to translate…

> The other big one is futures. There’s still no futures executor in std. Async crates have to decide if they want to tie themselves to a single executor (like Tokio) or be compatible. There is no async stream api in std. No async file api. And so on. It’s a compatibility nightmare.

We need useful traits to abstract over async runtimes. But there are a lot of design points for runtimes so this can't ever go into std. There is embassy, for embedded systems. There is monio and glommio built around io-uring. Then there is smol intended to be simple and lightweight. And then there is the kitchensink of tokio.

Clearly embassy is the one we want in the standard library. /s (It is the only one I personally would have a use for. But no, I don't think any of them belong in std. Traits to abstract over them? Yes, absolutely.)

But even your other example of strings: there are many design points for strings too, that might be better fits for specific use cases: string builder (with a capacity, what String in rust is), copy on write, small string optimisation (like compact_str), even interned strings. So your example of a vocabulary type is somewhat flawed, a better example would be Option or Result. Even anyhow and thiserror build on top of those vocabulary types.

Re: Malicious Rust crate Arrayref runs a build-time payload

#352

Earlier quoted context omitted.

This is spot on. I am extremely uncomfortable with the large number of transitive dependencies that end up in pretty much any non-trivial rust application. No amount of memory safety will save us if a tiny, ubiquitous library that nobody scrutinizes because it’s nested eight layers down the dependency graph gets compromised. I think Go apps tend to have better dependency hygiene because the language has a better stan…

If those transitive dependencies are baked into the language runtime, how is anything materially different? You just shift the vector around.

Because the standard library of a programming language has a lot more eyes on it than one of the many small dependencies does.

Re: Malicious Rust crate Arrayref runs a build-time payload

#353
post #240

Earlier quoted context omitted.

On the other hand, there are some bad Go standard libraries that are frozen in time.

Yeah, but I will take a not great library that works everywhere the compiler does, than be at the whims of which platforms are supported by 3rd party libraries. I can use most of the clunky Python, Java, .NET and if it must be, Go, standard libraries, than hunting down for dependencies with platform tier support and such.

Which is how you get the mess that is the standard library of C++. Where regex is an unusably slow joke and everyone uses third party libraries for that instead.

And tons of parts of the standard library (and language) being cordoned off as "legacy, don't use for new development". Of course figuring out what you shouldn't use in C++ can be hard too. It isn't well documented (or universally agreed upon), and it takes having it as a full time job to be able to keep up with these days.

No, I much prefer the way Rust is doing it.

Re: Malicious Rust crate Arrayref runs a build-time payload

#354

Earlier quoted context omitted.

Those aren't the only two choices. We also have the classic example of PHP with numerous not safe stdlib ways to use mysql. To me the answer is still to vendor your dependencies and don't be on the bleeding edge of updates unless you're willing to invest the time into validating them.

> We also have the classic example of PHP with numerous not safe stdlib ways to use mysql. I think it goes without saying that emulating PHP is rarely a good decision.

Don't forget C++ where large parts of the standard library are unusable (regex is slow and unfixable) or soft deprecated (dont use iostreams for formatting, use std::format, etc).

No, I prefer what rust is doing. It suits a system programming language. Which is what Rust is.

Re: Malicious Rust crate Arrayref runs a build-time payload

#355
post #269

Earlier quoted context omitted.

Yep. Sorry for the spam, but look at this, compiling "yazi" from source (ie a relatively simple TUI file manager) 676 dependencies: Downloaded by_address v1.2.1 Downloaded block-buffer v0.12.1 Downloaded block-padding v0.4.2 Downloaded adler2 v2.0.1 Downloaded color_quant v1.1.0 Downloaded blowfish v0.10.0 Downloaded byteorder v1.5.0 Downloaded bytemuck_derive v1.12.0 Downloaded futures-sink v0.3.34 Downloaded bs58 v…

'bs58' jumped out at me as a random looking package name. It implements the base58 encoding, which is used primarily by... Bitcoin. I'd love to see the explanation of why "a TUI file manager" needs a crate closely associated with crypto coins and not much else. It is precisely this kind of thing that makes Rust a no-go for most enterprises. "I just want a CLI tool." "Congratulations, your servers are mining crypto!"…

It doesn't actually use it, this is just referencing it in the dependency graph (Cargo.lock). bs58 is an optional (feature-gated) transitive dependency of another crate, which is never referenced at all in the top-level crate. The build.rs doesn't run or anything.

I believe there's (several) open issues about changing this behavior of the lock file, but I have moved on from Rust so don't know the status of things.

That said, this is confusing behavior. I remember I first noticed it when a bunch of crates were showing up in my lock file for every OS under the sun, even though I was specifically using a "wayland" (linux-only) feature.

Not to defend Rust's crazy culture of dependencies, mind you.

Re: Malicious Rust crate Arrayref runs a build-time payload

#356
post #107

Earlier quoted context omitted.

cargo add + rust-analyzer instantly executes build.rs before you have a chance to audit the code. Cargo, please PLEASE give me a way to disable third-party build.rs and whitelist the ones I need. And please loudly mark any update that adds a build.rs where there was none before.

So, don't add dependencies before you audit the code? That seems like a pretty reasonable ask to me.

You audit the code, then you run cargo update and you are pwned. Asking the user to not make mistakes is the c++ approach to security - it doesn’t work.

Re: Malicious Rust crate Arrayref runs a build-time payload

#357
post #269
post #79

Rust suffers from the same faults as the JS ecosystem. Any significant crate imports hundreds if not thousands of dependencies. The probability that one of the authors gets targeted by AI-assisted attacks is just too high. Also most of these dependencies provide a breadth of features that the end package does probably not need.

Yep. Sorry for the spam, but look at this, compiling "yazi" from source (ie a relatively simple TUI file manager) 676 dependencies: Downloaded by_address v1.2.1 Downloaded block-buffer v0.12.1 Downloaded block-padding v0.4.2 Downloaded adler2 v2.0.1 Downloaded color_quant v1.1.0 Downloaded blowfish v0.10.0 Downloaded byteorder v1.5.0 Downloaded bytemuck_derive v1.12.0 Downloaded futures-sink v0.3.34 Downloaded bs58 v…

I use nnn[0], a C tui file manager, and from the makefiles, you mostly need

  readline
  pcre
  ncurses
  pthread
  and POSIX (and some unix thingies)
Which is why I love C projects, even with all the footguns. You have libraries with nice API that lets you write software without being on a treadmill to update the code every few months.

[0] https://github.com/jarun/nnn/

Re: Malicious Rust crate Arrayref runs a build-time payload

#358
post #255

Earlier quoted context omitted.

> The bad package version has also just disappeared from crates.io with no indication its been yanked. So, yanked crate versions do have an indication on crates.io. (Here's an example: [1]) The Rust blog post uses the word "deleted", and I'm guessing a bit here, but I think they mean that literally, and that the version here is deleted , not yanked. And I think that would be more appropriate: a yanked crate is still…

> That wouldn't be desirable in the case of a compromised crate: you don't want a download occurring at all. Sure you do; you just don’t want the crate to be made available to people trying to make use of the crate as regular downstream consumers. You still want the crate available for download for analysis . You especially want to be able to deterministically reproduce the vulnerable version of your software that yo…

Sure, I'm using "deleted" here to mean a third state more unvisible than "yanked"; I'm not trying to specify exact semantics about said third state, simply that it (a.) isn't yanked, and (b.) yanked's semantics are probably undesirable here and a third state has merit.

Yes, I agree with you that analysis is good.

Re: Malicious Rust crate Arrayref runs a build-time payload

#359
post #309

Earlier quoted context omitted.

The problem isn't the language here, it's cargo executing build.rs from dependencies which necessarily allows arbitrary code execution.

(as I and others have mentioned in the thread): The attacker can just move the malicious code from build.rs to lib.rs (ie. build-time -> test/execution-time). Then the problem is the language, as the grandparent observes.

Sure, but I don't expect build to execute arbitrary code. That's a big difference.

It's like if `git clone` ran random stuff from the cloned repo.

Re: Malicious Rust crate Arrayref runs a build-time payload

#360
post #318

Earlier quoted context omitted.

A package redacted for legal reasons should still be able to be built too! Presumably one or the other side of the relevant suit will need the package as evidence! I would suggest that such packages should simply require authenticated access + manual “write an email to ask to have your account be put on a whitelist”-driven authorization. Such a package would still be there (in its redacted state); but attempts to dow…

> A package redacted for legal reasons should still be able to be built too! Presumably one or the other side of the relevant suit will need the package as evidence! This doesn't make sense if the legal reason is accidental release of secrets or PI, in which case you absolutely do not want to leave it up. I'm not talking about things like github tokens here, those can be revoked. But actual secrets or PI where that i…

I mean, unless the party you’re concerned about having your secret is the maintainers of the package store itself, what’s the functional difference between “it’s deleted from our servers” and “it’s marked private so only the author [or admins of the author’s org, insofar as user accounts are org-bound] can still download it”?
Post reply on HN