Malicious Rust crate Arrayref runs a build-time payload (safedep.io)
316 points by abhisek 7 hours ago
cube00 6 hours ago
GitHub really needs something finer-grain then just pretending the repo never existed during these incidents. [1]
The bad package version has also just disappeared from crates.io [2] with no indication its been yanked. There's no security advisory there either [3] "No advisories found for this crate."
I feel crates.io was unprepared for a security incident like this since they're managing the response [4]
[1]: https://web.archive.org/web/20260820145918/https://github.co...
[2]: https://crates.io/crates/arrayref/versions
[3]: https://crates.io/crates/arrayref/security (I'd give an Wayback link but that's also broken https://web.archive.org/web/20260820150747/https://crates.io...)
[4]: https://github.com/rustsec/advisory-db/issues/3161#issuecomm...
deathanatos 4 hours ago
> 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 downloadable by cargo, if your lockfile is locked to it already; yanking only prevents lockfiles from newly automatically acquiring a lock on that version. That wouldn't be desirable in the case of a compromised crate: you don't want a download occurring at all. The tradeoff of "break those with locks on the crate" tips to being worth it.
That said, I agree with you, though: I think this state (if it is "deleted" and not yanked) should be plainly indicated on the crate's versions page. (Even better would be if it came with a link to, e.g., the blog post or a RUSTSEC so that you could find out why.) (& I think perhaps the docs for yank should point out whether or not it is appropriate in the "compromised crate" scenario, and if not, what to do instead.)
derefr 2 hours ago
> 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 you already built.
I would posit that most package ecosystems should treat “contains an exploit” as its own package state; mostly ignore them; but still be aware of their existence.
In other words, if there’s any other non-exploited option under your version constraints, the dep should resolve to the nearest non-exploited version, even if older. But if it’s the only version, or if you have pinned the exploited version, then the packager should see it, but normally refuse to interact with it—i.e. refuse to lock to it if it’s the only version; or refuse to fetch it if it’s the locked version.
I say “normally” because you should be able to bypass this with a flag / env-var to the packager that basically means “I’m building this for forensic analysis, not for running.”
fc417fc802 20 minutes ago
wavemode 24 minutes ago
landr0id 5 hours ago
[3] is no longer true. They're definitely not unprepared for an incident like this. It's not the first time they've done it and they published an update to their process in Feb:
https://blog.rust-lang.org/2026/02/13/crates.io-malicious-cr...
Not having an advisory INSTANTLY available isn't a sign of a decaying org. Chill.
cube00 4 hours ago
> They're definitely not unprepared for an incident like this.
We shouldn't need to resort to pasting `find` commands [1] into the shell from blog posts to tell if we're compromised.
`cargo audit` should be reporting if these packages have been downloaded. The "What you need to do" section of the blog should be run `cargo audit`
> Not having an advisory INSTANTLY available isn't a sign of a decaying org. Chill.
The GitHub issue was opened 8 hours ago. The cargo.io team also acknowledged it 8 hours ago. [2]
> [3] is no longer true.
Previously published versions shouldn't just disappear from the list. There's still nothing there to indicate a version was yanked.
[1]: https://blog.rust-lang.org/2026/08/20/supply-chain-attack-on...
[2]: https://rust-lang.zulipchat.com/#narrow/channel/318791-t-cra...
eminence32 4 hours ago
thayne 4 hours ago
qwertox 5 hours ago
> GitHub really needs something finer-grain then just pretending the repo never existed during these incidents.
Google should read this too. They simply remove Android apps and Chrome extensions without a single word. No page explaining why they removed it, if i was at risk.
einrealist 2 hours ago
If anyone wants to create a revision to RFC 9110 :)
HTTP/1.1 309 Security Advisory
Location: https://acme/aaargh-another-advisorycosmic_cheese 6 hours ago
I think we should be taking a more “batteries included” approach to language and library design. The entire reason we’re in this mess is because we’ve decided it’s ok or maybe even preferable if stdlibs are rail thin, rendering base languages near-unusable.
I can very easily build a highly functional, pleasant to use Apple platform app with 5 or fewer top level dependencies. In many cases, I reach for between 0-2 total.
There’s no reason why this can’t be replicated elsewhere. The key is to make the programming language reasonably robust with at least 80% of common non-UI dev needs built in and put the remaining 20% and UI bits into a small family of well-supported, community-embraced, preferably first party libraries.
That would make it unnecessary to pull in foreign dependencies in the overwhelming majority of projects. What few do get pulled in becomes lightweight, easily verifiable syntactic sugar or libraries with purposes too niche to be worth targeting.
Of course this approach can go wrong too. You could easily end up with a monster like Boost, but that comes down to project administration keeping creep under control and proper modular design.
fc417fc802 5 minutes ago
I don't see the problem with boost? Isn't that a perfect example of your well supported, community embraced option? I certainly feel much safer pulling something in from boost via the official debian repos than I do pulling a random package with npm or cargo or etc.
Primarily I think the underlying concern has to do with the pathway for authoring code. When you have contributors whose submissions are gated with a rigid third party process and where that third party is the one responsible for curating the code (as opposed to the author also being the curator as well as the publisher) then you have the possibility to catch a lot of wrongdoing before it succeeds.
segphault 4 hours ago
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 standard library, which results in better culture around dependencies.
I also think it’s frustrating that both cargo and npm totally ignore the decades of prior art from Linux distributions that have figured out good ways to improve dependency management. We’d be in better shape if there was a community curated subset of known-good dependencies that are release-managed together that the broader ecosystem could build on, sort of like Ubuntu having “main” and “universe”.
CrimsonCape 20 minutes ago
I learned programming from C# which has an excellent standard library. Just recently started using Go which seems to have a good standard library. Been using python for years, can't say I ever had a complaint about the standard library.
Rust meanwhile seems to be following some "no standard library" philosophy.
I feel like there's an opportunity out there to become like an amoeba: fund and build a third party Rust standard library, absorb absolutely everyone who is so grateful to have a library, and then get so big absorb Rust itself.
__david__ 2 hours ago
I think Go ends up with fewer dependencies mostly because there is more friction in finding them. With rust (and npm) you just "cargo search xxx", then "cargo add xxx". Go makes you web search and poke around github looking for something. It's not onerous or anything, but just that extra step slows things down just a bit. C projects tend to have the least because it's even more annoying to add them and you have to create build commands that deal with slightly different distributions (and learn makefile+pkg-config or cmake, or autoconf).
Certainly having a larger stdlib helps Go projects keep their deps down, but I don't think it's the real reason.
overfeed 33 minutes ago
teach an hour ago
saturn_vk 26 minutes ago
nemothekid 3 hours ago
>There’s no reason why this can’t be replicated elsewhere. The key is to make the programming language reasonably robust with at least 80% of common non-UI dev needs built in and put the remaining 20% and UI bits into a small family of well-supported, community-embraced, preferably first party libraries.
The big reason is money & time. Maybe less so today if you are happy with an AI generated stdlib, but I don't think it's fair to compare Rust (built by Mozilla, who's primary product is an open source web browser) to Swift/AppKit (built by Apple, 4.6T marketcap at the time of writing).
When Go was released it had an amazing stdlib, but that was because Google was funding it.
cosmic_cheese 2 hours ago
There's probably to truth to this, but I would weight the design intention behind the language just as or more heavily than available resources.
Swift was intended from the start to not only replace Objective-C and all of its use cases, but also take on new use cases and bring a number of features from other languages that were newer and had different dominant paradigms.
Certainly having a juggernaut like Apple behind it has been instrumental in its success in achieving those goals. That said, a community-lead project with similar aims could probably achieve those aims as well, given enough time.
I think it's just rare for enthusiast-led projects to set out to do such things. My theory on why things tend to go that way is that the types of people to start programming language projects tend to heavily lean nuts-and-bolts and theory with a purist/idealist sort of mentality that's more concerned ideological purity than practical usability.
So to sum this all up, a community-run practical, multi-purpose, batteries-included language likely needs to at least partially designed and helmed by product engineer types so it doesn't end up anemic and stuck in an ideological rut.
echelon 3 hours ago
Python is batteries included, but all the batteries have corroded.
Look at C++'s long in the tooth STL.
You don't want to marry a language to fast aging libraries you have to support for eternity. Better libraries always naturally emerge.
Rust's decision here is fine.
The only thing I'd like to see is the ability to programmatically limit transitive dependency count or depth in Cargo. I'd also like crates to specify whether they limit their own deps and whether they have panick-y behavior or not.
Pannoniae 29 minutes ago
smw 2 hours ago
im3w1l 2 hours ago
rfgplk an hour ago
> I can very easily build a highly functional, pleasant to use Apple platform app with 5 or fewer top level dependencies. In many cases, I reach for between 0-2 total.
> There’s no reason why this can’t be replicated elsewhere. The key is to make the programming language reasonably robust with at least 80% of common non-UI dev needs built in and put the remaining 20% and UI bits into a small family of well-supported, community-embraced, preferably first party libraries.
I wholeheartedly agree. Most standard libraries out there (when I say most I easily mean of 99% languages that I know) have pitifully tiny implementations. They at most provide for string parsing, io, a bare networking layer (that's at best a wrapper around the POSIX syscalls), threading and that's it. If you want to do anything more complex, you either have to roll it yourself or use an assortment of the "blessed libs" for any given language, that may or may not work properly, and may or may not even work well with each other. I got pissed off by this at some point so I decided to go ahead and roll my own standard lib that would actually have everything I need to.. actually develop apps. Now I know most people probably aren't going to be using it (mainly because its functional API isn't what most C++ devs want) but for me it's actually been brilliant.
mightyham 4 hours ago
Rust has a sizable and well featured standard library at this point. I think it would be absurd to claim that the base language is "near-unusable" if you are using it for system programming, which is its intended use case.
Huge standard libraries make sense for Java, Go, Apple platform etc. because they are developed by giant enterprises that can manage the overhead. Thinner modular systems are a more natural fit for open source development.
cosmic_cheese 3 hours ago
It’s being used for a wide variety of other purposes however, and so perhaps it’s time to adapt to that reality.
While overhead is a real concern, I think it’s often blown out of proportion. Once a language achieves a certain baseline of stability and isn’t in constant flux and the standard library matures, changes become infrequent and maintenance load is low. The work is heavily front-loaded.
yoyohello13 6 hours ago
This was actually the main thing that put me off of Rust. I get the argument for a small std lib. I just also don’t agree it’s worth it. Go seems to handle having a batteries included standard lib just fine.
afdbcreid 44 minutes ago
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.
Pannoniae 28 minutes ago
0cf8612b2e1e 5 hours ago
On the other hand, there are some bad Go standard libraries that are frozen in time.
pjmlp 2 hours ago
rirze 5 hours ago
bigstrat2003 4 hours ago
leecommamichael 6 hours ago
The Odin programming language does this! It has also decided not to provide a package manager.
hnlmorg 4 hours ago
Go took the same approach and ended up having to implement a halfarsed one when everyone started implementing their own.
leecommamichael 4 hours ago
Ygg2 5 hours ago
Spoiler alert! JavaScript has no language provided package manager.
If Odin gets moderately successful someone will probably reinvent it.
leecommamichael 5 hours ago
TZubiri 2 hours ago
>I think we should be taking a more “batteries included” approach
https://www.youtube.com/watch?v=GZOuz-SG7-g
Funny how you skipped "I should build my own batteries" and when straight to "increasing and centralizing the duties of your main gratis 'vendor'".
cosmic_cheese 2 hours ago
I don't like the "bring your own" approach because unless one happens to be an absolute tour de force 10x engineer unstoppable god of a programmer (which most of us, myself included, are not), whatever you build is never going to be as well-rounded, fleshed out, and complete as something built by a larger organization, especially when it comes to UI libraries (which are monstrous projects if done right, e.g. meeting accessibility requirements).
I'm happy to contribute to a larger effort but anything I can build on my own is going to be a thin, flimsy happy meal toy compared to something with the backing of a company or well organized FOSS project.
cesarb an hour ago
TZubiri 2 hours ago
cpill 2 hours ago
with LLMs it's becoming more common to just vibe up anything you need that might be missing. even if there is an available package you can pull in. the most secure option as well
ramimac 7 hours ago
Thread on the post from main rust blog: https://news.ycombinator.com/item?id=49372853
Direct post link: https://blog.rust-lang.org/2026/08/20/supply-chain-attack-on...
Initial report: https://github.com/rustsec/advisory-db/issues/3161
Other vendor posts:
* https://www.stepsecurity.io/blog/arrayref-rust-crate-supply-...
* https://research.jfrog.com/post/arrayref-proc-macro1-crates-...
* https://www.aikido.dev/blog/two-popular-rust-crates-arrayref...
jakubadamw 6 hours ago
Cargo desperately needs sandboxing for build.rs scripts. It’s been attempted before, but didn’t go very far¹.
¹ https://rust-lang.github.io/goals/2024h2/sandboxed-build-scr...
sempron64 2 hours ago
Sandboxing is a mitigation but a very limited one. The library itself can contain a malicious payload -- rust code most often ends up as native code executed on the host.
I think we may need to enter a world where there are fewer, heavily audited, libraries and dependency depth is limited. Allowing unvetted dependencies to be installed by default is not a good way forward. App stores have a similar problem and I think a lot of lessons have been learned there that can be applied.
k_roy 2 hours ago
That world can’t exist unfortunately, because the minute someone wants a feature that isn’t in your core libraries, you just create a new library and we’re back to now.
7373737373 2 hours ago
That's why languages need sandboxing at runtime as well
abhisek 6 hours ago
This is exactly what PMG is designed for ie. install/build time process level sandboxing. It currently doesn't support cargo, but I believe the challenges are same.
Here is my learning building PMG:
Sandboxing is good when the workload is predictable, and the goal of sandbox is to guard against exploitation of vulnerabilities, like sandbox protecting chrome tabs (renderers). But unfortunately build scripts are not predictable, at least not in npm/pypi world and I have seen build scripts doing weirdest of the things which is no different from malware. When popular packages do weird things, build breaks and users end up turning off the sandbox. This is a perpetual problem to deal with while building sandbox (or any least privilege solution) to protect unbounded workloads.
Asraelite 5 hours ago
The "How PMG Works" section on Github does not actually explain how it works
swiftcoder 6 hours ago
build.rs by design can run absolutely anything. There tons of build.rs scripts that invoke a whole-ass C compiler toolchain to build and link C dependencies...
It isn't so much a question of sandboxing build.rs, as fundamentally changing the way that foreign dependencies are integrated into the rust toolchain (i.e. moving from a rust-centric system like Cargo to something more general like buck2)
mike_hearn 3 hours ago
Worth noting that the JVM ecosystem doesn't have this issue because there is no notion of installing dependencies, and the package managers are just downloaders with nothing else. No build.rs equivalent.
To solve the problem of native/C dependencies, they just bundle pre-compiled libraries as data files.
Rust could do the same thing.
ChrisSD 2 hours ago
pie_flavor 2 hours ago
kibwen 5 hours ago
The vast and overwhelming majority of build scripts are building C code, so the other solution is to move away from integrating with C dependencies to native Rust dependencies, in which case adding friction to build scripts would be less noticeable.
robhlt 4 hours ago
thayne 4 hours ago
Panzerschrek 6 hours ago
Sandboxing for build scripts can't work properly. If you sandbox too much, some necessary stuff can't be done. If you sandbox too little, it has no practical value.
amluto 4 hours ago
As an easy start, how about letting build scripts read /usr, read and write a temporary build directory, have some /tmp scratch space, and be allowed to write its final output artifact. No network and otherwise isolated from the rest of the system.
I would argue that, if a build script doesn’t work in the setting, then it doesn’t deserve to be installable by a default cargo command.
kibwen an hour ago
lobofta 5 hours ago
So let each build script define its own level of sandboxing and then users can determine whether they are okay with that level or not, e.g. `cargo build --sandbox-level=...`
jurgenburgen 5 hours ago
weinzierl 6 hours ago
Sandboxing just build.rs would only be be a minor inconvenience for the attacker, nothing more. The attacker can always as easily compromise the binary you build and as soon as you run it (e.g. in a test) you are owned.
It would be a big pain for many that are in the unfortunate position to really need build scripts, though.
Aurornis 5 hours ago
I imagine it would be sandboxed by default with an escape hatch to run build scripts outside of the sandbox with user verification. It makes people stop and think about what’s happening. Not perfect, but it does help. When working on JS ecosystem projects I manually approve build scripts and spend some time researching dependencies with build scripts to see if I can avoid running the build script. Some people will ignore it and run everything, but it’s a huge step in the right direction to make it operator-decided.
insanitybit 6 hours ago
It would be more than a minor inconvenience. I can handle sandboxing my tests and production infra, but I can't handle sandboxing build scripts because I don't own that code in any sense.
kibwen 5 hours ago
At the very least, it wouldn't be overly onerous when adding a dependency that requires a build script to require an opt-in via Cargo.toml, e.g. `build-script = true`. You'd make it viral so that any transitive dependency that requires a build script would affect its parent, then add the key as defaulting to `true` so as to not break backwards-compatibility, then switch the default to be more restrictive over a new edition. (This same key could be used to prevent proc-macros from having arbitrary system access as well, where by default proc macros could be compiled to WASM and run in a WASM sandbox and treated as pure functions.)
bhickey 2 hours ago
I'd like to see a "no-build" option to blocks depending on crates using build.rs
somat 6 hours ago
I mean sure, but anything the build script could do, the build artifact could also do, That is to say, if you don't trust your source why do you trust the thing it compiles into?
burnt-resistor 6 hours ago
Never going to work. Crates must be audited for behavior before use.
Aeolos 6 hours ago
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.
praseodym 5 hours ago
pie_flavor 2 hours ago
bigstrat2003 4 hours ago
burnt-resistor 3 hours ago
IshKebab 3 hours ago
I think it would be a good start if crates at least had to opt in to a build script, and adding one later would require permission from crates that depends on it.
The vast majority of crates don't need build scripts, so it is vaguely feasible to audit the list of crates you use that might need them.
krautsauer 6 hours ago
https://news.ycombinator.com/item?id=49374811
(Oh and btw, proc macros also run arbitrary code.)
quotemstr 6 hours ago
There's no good reason a proc macro can't run in a no-IO sandbox by default. None. Doesn't require a language change. Doesn't require some microvmcapabilityeffect BS. It requires looking people straight in the eye and saying "no" when they complain about needing to prompt for privileges.
2OEH8eoCRo0 an hour ago
How many times do we need to learn that sandboxing won't magically save us.
fwlr 41 minutes ago
From the article: “[for Windows victims,] the [malicious] build script [fetches the attacker’s remote payload,] writes [it] to %TEMP%\rust-setup.ps1 and starts [it] through a VBScript launcher under wscript.exe, with a comment in the source explaining why:”
And the comment is:
// ShellExecute via WScript escapes Cargo's job object; spawned children otherwise
// keep the build script (and `cargo build`) waiting until they exit.
So the malicious build script has a helpful comment (???), written in a familiar “terse nouns verbing” style (!!!).Would it be gauche to speculate? Maybe some script kiddy sweet-talked Fable into dropping its safeguards, or maybe Anthropic is doing a training run for Fable 5.1 and the air-gaps aren’t gapping.
nottorp 6 minutes ago
Eh, just because the likes of Anthropic are only threatening you with their latest model, it doesn't mean older models can't do exploits...
hbbio 6 hours ago
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.
dwroberts 5 hours ago
My experience has been that it has a major advantage, in that freeze + offline actually work properly. You can collect the dependencies you need once, put them in version control and never ever talk to remote registry again
quikoa 4 hours ago
A language without a large stdlib pushes this that functionality into (transitive) dependencies. I hope more language will adopt batteries included approach.
thayne 4 hours ago
No stdlib will ever include all the "batteries" you need. And large stdlibs have their own set of problems, like stagnation, tying the library version to the language version, backwards compatibility garantees preventing evolution, and either needing a wide range of domain experts to maintain it, or having developers maintain components they don't have a deep understanding of.
I think the sweet spot is having an ecosystem of "blessed" libraries that are reviewed for security and quality, but are versioned independently of the language, and maintained by subject matter experts.
rfgplk an hour ago
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 v0.5.1
Downloaded critical-section v1.2.0
Downloaded fnv v1.0.7
Downloaded bytemuck v1.25.2
Downloaded form_urlencoded v1.2.2
Downloaded futures-macro v0.3.34
Downloaded futures-io v0.3.34
Downloaded blake2 v0.11.0-rc.6
Downloaded find-msvc-tools v0.1.11
Downloaded funty v2.0.0
Downloaded fdlimit v0.3.0
Downloaded ff v0.14.0
Downloaded foldhash v0.2.0
Downloaded bon v3.9.3
Downloaded fdeflate v0.3.7
Downloaded darling_core v0.23.0
Downloaded bon-macros v3.9.3
....
Compiling clap v4.6.6
Compiling tokio-util v0.7.19
Building [===============> ] 451/676: ecdsa, exr, yazi-shared, regex-automata,account42 5 hours ago
Yes, the lack of a language package manager for older programming languages is a feature.
fidotron 6 hours ago
Doing software development outside of strict containerization, at the very least, looks increasingly prone to disaster.
Yes, we can argue about the culture of package management (as some of us have with especially npm from day one), but it's done, and your colleagues or AI sidekicks cannot be trusted not to download whatever and try to build and run it. All you can do is limit the effective blast radius.
jonahx 6 hours ago
Proper and easy to use support for sandboxes at the OS level, or better yet capabilities, seems like the only long term solution.
Many things I run I want to limit to r/w a single dir, and to have to request permission to make network calls.
hnlmorg 4 hours ago
Two problems with this:
1. There isn’t a single universal standard for sandboxing across all the different platforms that are supported by Rust.
2. Even if there were, if you’re compiling untrusted code then why would you trust the built output?
If you’re building the create then I’d argue that any preventative steps afterwards is akin to closing the barn door after the horse has already bolted.
jonahx 3 hours ago
fidotron 4 hours ago
jfklgkdkdnn 6 hours ago
minimum-release-age
kibwen 5 hours ago
Cargo has been working on min-publish-age, and the PR to stabilize the feature is in its final comment period and currently expected to land in Rust 1.100: https://github.com/rust-lang/cargo/pull/17335#issuecomment-5...
cesarb 38 minutes ago
llleeeoooh 5 hours ago
is there a way to set up without using the nightly build?
xgulfie 5 hours ago
what if I need a dependency my teammate released 5 minutes ago
hnlmorg 4 hours ago
wotb 4 hours ago
tyrchen 2 hours ago
When several supply-chain attacks hit the npm ecosystem a few months ago, I built SBE: https://github.com/tyrchen/sbe.
It provides sandboxing for arbitrary CLI commands using Seatbelt / SBPL on macOS and Landlock LSM + seccomp-bpf on Linux. You can use it to protect local dependency builds, or integrate it into GitHub Actions to add an extra layer of protection to CI.
Feel free to give it a try — I’d love to hear your feedback.
vatsachak 7 hours ago
All those folks telling me to update my dependencies, this is why I don't do it. It's not laziness, it's undeniable foresight.
beej71 6 hours ago
As long as your versions don't have any security issues...
pixl97 6 hours ago
I mean, yes, update your dependencies. But probably after a week or so after they've been release and tested by the first penguins willing to jump into the ocean.
kmeisthax 6 hours ago
Holding periods for new updates are a good idea, but I would also prefer having a tool that could provide diffs of the entire project state pre- and post-update; including transitive dependencies being added or removed. Git diffs won't show you that information, by design.
abbadadda 6 hours ago
What purpose does “undeniable” serve here? This tips over into hyperbole, in my opinion, whereas “it’s foresight” is much simpler and stronger. YMMV.
pluralmonad 6 hours ago
I think it was to make the tongue-in-cheek nature of the comment more apparent.
jfklgkdkdnn 6 hours ago
rirze 5 hours ago
There's a reasonable solution to this. Tools like `cargo-audit` can tell you if a crate has security issues and guide you towards an update. You don't have to blindly update all dependencies this way.
tancop 6 hours ago
We need effect based languages now. It's the only way to guarantee policies like no network, no file access, no unsafe code or FFI for a library before it even compiles. If anyone from epic is reading this please give us a timeline for open sorucing the Verse compiler.
In the mean time I think it's possible to hack Cargo and run all build scripts in a microVM. The blast radius will be limited to malicious code in the binary instead of uploading all your CI secrets and deleting the whole hard drive.
jmull 5 hours ago
I think this is an attractive chimera, but will never be popular and will only be used much in specific domains.
The thing is, trust is a massive optimization. If you believe code from X is competently made and not malicious, you can accept that code without any additional overhead. (Building trust is a significant effort, but trust begets trust, so there's a resonable path from starting small to scaling.)
It's not that these mechanisms that require less trust (none of them eliminate it, BTW, when you examine them) can't work. It's that they'll inevitably be outcompeted by trust-based systems (in most domains).
E.g., compare the effort of creating a new, full featured, general purpose language, promoting it, building and maintaining all the tooling and documentation around it to support it, etc to the effort of creating and maintaining a curated package repository of trusted packages (and/or adding trusted code to extend the standard library) for existing language X.
(It's not clear to me you could provide enough value from a new language focused on effects that you could convince any but a few from adopting it at all, even if it dropped from the sky fully formed with all tools, docs, etc. in place from day one.)
vaylian 6 hours ago
> It's the only way to guarantee policies like no network, no file access, no unsafe code or FFI for a library before it even compiles.
It's not the only way. You can sandbox processes. I think sandboxing is the much more reasonable approach, because in the end of the day, there are still closed-source software products where you can't demand that the manufacturers use certain language safety features.
kevincox 5 hours ago
Sandboxing the process only works well when the malware requires more capabilities than the software itself.
So if your software needs to make HTTP requests and read the filesystem then the malware will be able to make HTTP requests and read the filesystem, which is enough for a ton of malware. Sure, maybe you can limit the directories it can access a bit and possibly some sort of network filtering, but it isn't a silver bullet.
Capability security in-language would make a huge difference, because the more granular you "sandbox" the less likely it is that the compromised component has the access it wants. For example if the HTTP client library is compromised maybe it can't access the filesystem so can't steal your cookies. Or maybe like in this case no permissions were needed at all and despite the process having enough capabilities for malware this malware can at worst return bad values and try to chain this to an exploit which is far more difficult than just running it itself.
cpuguy83 5 hours ago
throwaway894345 6 hours ago
I don’t even understand what a capability based language is, but presumably closed source software wouldn’t apply here? Is it common for closed source software to give the source code to customers to build?
bluGill 6 hours ago
7373737373 2 hours ago
rtfeldman 6 hours ago
I think the only language that's used in production where malicious dependencies can't do arbitrary effects is https://roc-lang.org - but it's a pre-0.1.0 language and as such its production usage is extremely minimal for now.
rrook 5 hours ago
Some shameless self promo - I'm working on one!
insanitybit 6 hours ago
https://github.com/insanitybit/witchy
This is why I'm building this language. It's capabilities based. Build scripts can't just do whatever the hell they want to, everything is auditable, and it layers its sandboxing.
It's for fun and anyone looking should understand that this is AI driven building with human driven design, but the goal is to demonstrate.
prpl 5 hours ago
I have been working on a cross platform way of sandboxing without a VM:
jooops1 5 hours ago
Can you explain how an effect based language helps here? Also to note filesystem access can allow network access on many systems and also the other way around.
burnt-resistor 6 hours ago
More than that, we need capability-based languages. No capability passed to it, no permission.
mike_hearn 3 hours ago
Why not object capability languages: https://blog.plan99.net/why-not-capability-languages-a8e6cbd...
burnt-resistor 2 hours ago
kibwen 6 hours ago
First we need capability-based OSes, like we should have had decades ago if worse-is-better hadn't stuck us with Unix. I don't need to care whether or not a program was written in a capability-aware language if the OS fundamentally takes care of that for me.
grommz 5 hours ago
ptx 5 hours ago
burnt-resistor 2 hours ago
throwaway894345 6 hours ago
Why does every build have the ability to run arbitrary code by default in the first place? That seems like something you should opt into only under very specific scenarios and even then it should probably be built around a WASM sandbox or microVM (as the parent suggested).
bluGill 5 hours ago
Because many many builds end up doing something just a little weird that the build system cannot handle by default. Ideally the build system would be fully property/dependency based and so it wouldn't have to run arbitrary code. In the real world everybody has something weird about their build that the build system cannot make work.
This is partially because for nearly every project the build system is something they need and don't care about. When they need something weird they hack just enough to make it work and never ask "how should the build system change so that this was a property instead of running code", and thus build systems are slow to improve. In a number of cases the build system did have a way to do that thing, but the person didn't know about it.
There are also a lot of code generators out there. I have yet to see a large project which didn't have their own code generator for something specific to their project (protobuf is an example from Google that has escaped and become useful elsewhere, but there are many others that are specific to one project. Yacc is from the 1970s, and stands for "yet another compiler compiler" - implying the idea was already common 50 years ago). You cannot have/use these useful tools without running arbitrary code.
skydhash 5 hours ago
quotemstr 6 hours ago
MicroVM this, effects that --- can we discuss security without needing to invoke bay area buzzwords?
The idea is "least privilege", and we desperately need it in computing. The precise technical mechanism we use to achieve it is less important than committing to the idea that a dependency doesn't run with full privilege of its host program and an install script doesn't run with full privilege of the programmer.
The original Linux seccomp is old enough to drink. It's always been possible to do things like expand macros in a no-IO environment. Nobody's bothered to do it over the past two decades. Why would anyone bother in the next two decades?
insanitybit 6 hours ago
The technical mechanism is exactly the issue to figure out, there's a reason why projects don't have this and it's because different implementations have different tradeoffs.
quotemstr 6 hours ago
hoppp 4 hours ago
The rust ecosystem is going to be hit by malware just like the NPM ecosystem. I have been saying it for years. They made the same mistakes or even worse mistakes because all it takes is a compromised serde to take the entire ecosystem down.
leecommamichael 4 hours ago
Here's a suggestion, do you think it could be this simple? If you write a package-manager, don't execute any of the downloaded code in an automated fashion. No hooks, no build-time metaprograms. If your language _needs_ metaprogramming to function, it's a huge secondary issue that I don't know how to solve. You can try to make a meta-program annotation which disables side-effects, but the metaprogram ultimately must write memory which expands the amount of code generated. All risk is introduced when the person downloading cannot preview the content in a safe place.
zarzavat 2 hours ago
Unfortunately it doesn't solve the problem because malicious code can still end up compiled into the user's program which they will promptly execute, possibly in production...
Supply chain attacks are not a problem that can be solved by a single silver bullet, however the biggest benefit comes from a combination of minimum release age + fresh 2FA required for every publish + automated scanning. This makes it considerably more difficult to pull off a supply chain attack and should be the baseline security for all package managers.
killme2008 3 hours ago
We really need Cargo RFC #3923 https://github.com/rust-lang/rfcs/pull/3923
It would allow projects to avoid newly published dependency versions until a configurable waiting period has elapsed.
npm has had a similar min-release-age feature for years.
killme2008 3 hours ago
It's a pity that progress has been so slow.
tsimionescu 7 hours ago
> arrayref is a small crate of four macros.
Why do so many languages fall into this horrible practice?
wasmperson 6 hours ago
There was a recent talk which explored this question (Dependency Cultures, by Richard Feldman):
https://www.youtube.com/watch?v=E82ly38YEEQ
Summary: it's cultural. Rust likely inherited the practice from Nodejs, who inherited it from Ruby. I think in Rust online spaces in particular there is also this undercurrent of "you're not smart enough to use certain parts of the language, so download libraries that handle that stuff for you."
igsomething 6 hours ago
The language also takes backwards compatibility very seriously, anything that goes into std "must be maintained forever". It is also argued that a large stdlib means the maintainers have less time to work on the language itself.
I understand not every language can have Go's amazing stdlib, but I would much prefer Pyhton's approach where every now and then some package/function from the stdlib gets deprecated/removed. Rust's 3rd party ecosystem is the worst thing from the language, worse than the compile times.
superxpro12 6 hours ago
i'd like to welcome you to the hell that is c/c++ dependency management. Make? cmake? qmake? conf? autoconf? configure? autotools? submodules??? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
nelup20 6 hours ago
bayindirh 6 hours ago
account42 5 hours ago
skydhash 6 hours ago
SSLy 6 hours ago
justinhj 6 hours ago
neutronicus 6 hours ago
The "npm-ness" of Cargo (centralized and standardized dependency management used at every opportunity) is generally pitched as one of the primary developer experience advantages over C++.
pjmlp 2 hours ago
vablings 6 hours ago
There are two reasons you might want to use a crate, The first being that you want to use a good solid implementation that you know someone has spent more time doing and works better than almost any solution you could integrate. The second is you don't want to spend time implementing that.
Writing macros in rust is a pretty horrible experience but it's not difficult
xdavidliu an hour ago
just to clarify, by "horrible practice" you mean macros?
bcjdjsndon 7 hours ago
Just like c++ thought threads wasn't a std library concern and then later changed they minds, rust will also change tac I predict
nicoburns 6 hours ago
Rust is actively incorporating more functionality into the stdlib. The functionality of this crate has been in std since 2024. The ecosystem is just slow to update (not everything is maintained, etc).
rvz 6 hours ago
The languages that have a poor standard library support have this issue and other languages encourage you to import tons of libraries to fix the problem.
This is why Javascript and Typescript suffer from this the most and has little to nothing to do with "popularity" and likely 9/10 of these npm packages import an external library.
Golang on the other-hand is just as popular and has a stronger standard library which people build against and it is encouraged to use its standard library rather than rolling your own or importing another package to solve the problem.
weinzierl 6 hours ago
Rich official standard library vs "import tons of libraries" are not the only two options.
Java's standard library had arguably also been poor for a very long time and "import tons of libraries" just had not been practical for most of that time because the tooling and ecosystem for that did not exist yet.
The solution was apache-commons and guava. Two large libraries with everything the developers heart desired and well maintained by large organizations.
For Rust be probably will never have anything exactly like that because requirements from no-std development to fully fledged backend service are too diverse, but there is still room for a small number of well maintained backed by reputable developers convenience libraries in my opinion.
wahern 4 hours ago
trembolram 6 hours ago
I don't want to see a large standard library for Rust. If something is added to the standard library, then it is very difficult to change it afterwards because backwards compatibility.
It would be better to have blessed crates in crates.io. The Rust core team would release or audit them. If the blessed crates need breaking changes, it can be done by increasing their major semantic version number. That can't be done to the standard library.
Actually, there could be a "trust" level for crates: 1. blessed crates by the Rust core team, 2. trusted developers, 3. untrusted developers. Or something like that..
sfdsfef3f3f 6 hours ago
Go has a stronger standard library for certain use cases like basic CRUD web applications, but a lot of the Go standard library is also extremely low quality (flag, container, image, json, log, math, path, regexp, sync, time). Many of these aren't usable outside of toy use cases and have weird edge cases all over the place. Over time many will probably get new incompatible versions just like json. The container package in Go is the worst collection library in any mainstream programming language by a huge margin. It's actually astounding how bad it is.
Mawr 3 hours ago
wasmperson 6 hours ago
I don't think this is true. People like to scapegoat the JS standard library but in reality most JS implementations have pretty featureful standard libraries, especially browsers. I've never felt the need to use any third-party libraries in the javascript projects I've worked on (except for maybe `ws`).
tsimionescu 6 hours ago
I don't think it's just that, though I agree they are clearly correlated.
The reason I don't think it's a sufficient explanation is that there is a clear history of large, 3rd party libraries being created exactly to supplement poor standard libraries. C++ has Boost, Java has Apache Commons (though Java also has a pretty huge standard library), arguably we could even say C has Posix/Win32/Cocoa.
I believe there is some deeper cultural reason why certain language ecosystems coalesce large utility libraries, while others prefer myriad tiny dependencies.
whstl 6 hours ago
DanielHB 6 hours ago
bryanlarsen 6 hours ago
I've never seen a non trivial Python or Go project without external dependencies. The dependency tree of comparable Go and Rust projects seem comparable, IMO.
QuadmasterXLII 4 hours ago
insanitybit 6 hours ago
Total nonsense. Python has a massive stdlib and there are malicious packages.
fukaiall 6 hours ago
Can’t agree more. If you take security seriously, you should consider using Go.
account42 5 hours ago
Only the ones that make it easy. Language package managers are a mistake.
pjmlp 2 hours ago
Unfortunely we haven't yet gotten a universal OS agnostic package, other than zip and tarballs.
MallocVoidstar 6 hours ago
They aren't trivial, at least: https://docs.rs/arrayref/0.3.9/src/arrayref/lib.rs.html#202-...
praseodym 7 hours ago
Post on the Rust blog: https://blog.rust-lang.org/2026/08/20/supply-chain-attack-on...
Discussion: https://news.ycombinator.com/item?id=49372853
praseodym 8 hours ago
Unfortunately Cargo doesn’t have security controls in place to prevent these kinds of attacks. For example pnpm has controls to allowlist install scripts for dependencies and will warn about new install scripts (without executing them).
There is an open issue for this: https://github.com/rust-lang/cargo/issues/13681
weinzierl 7 hours ago
Compromising the code that is then most likely run in a test instead of compromising a build script is just a very slight inconvenience for the attacker.
I share the dislike for arbitrary build scripts but restricting them will not help the supply chain issue in a significant way.
Also there are several ways to control build.rs execution in the Cargo ecosystem as well, for example with cargo-deny.
praseodym 6 hours ago
You’re right about attackers being able to change runtime code.
pnpm does have some other features to prevent supply chain attacks, so there is still something to learn from other ecosystems. For example pnpm has a cooldown period for new dependencies and can prevent trust policy downgrades (eg new version published without build provenance where older versions did have it). See https://pnpm.io/supply-chain-security
faern 6 hours ago
vlovich123 6 hours ago
Disallow lists are ineffective - better to disallow by default and require opt in.
Also, crates.io can defer serving up newly uploaded scripts that have a new build.rs / proc-macro dependency and warn publicly that a version introduces it.
Restricting build scripts 100% will help mitigate the impact, just not if you only deny it once. And they can develop other things like sandboxing for build scripts by default and escaping that to be the exception that has to be explicitly allowed.
Aeolos 6 hours ago
The problem is that build scripts run automatically without user consent or intevention.
`cargo add` is sufficient to compromise you, before you have a chance to even vet the code.
kibwen an hour ago
abbadadda 6 hours ago
Are there any plans to more seriously develop the standard library in Rust? Or is the plan to remain in this status quo where users of Rust import nonsense and the dependency tree explodes (or users are forced to invent their own wheel?).
Are there any comparisons between the state of the stdlib in C++ vs. Rust? I’d think that would serve as an excellent jumping off point to start chipping away.
speedstyle 3 hours ago
The standard library is not versioned, so any API*/behaviour there must be maintained forever. When you put it in a separate crate, you can make better interfaces or be displaced by a better crate, while old code still compiles against the version it was written for. So even code effectively maintained within rust teams (hashbrown, rand, regex) may be in separate crates, std is specifically for OS abstraction and a shared type vocabulary.
That doesn't mean you jump to importing nonsense or trivial dependencies. The top hundred are efficient, well-designed crates of the quality you'd expect in a large std like Go or Swift, sometimes even higher as people can write better implementations that they otherwise wouldn't (or wouldn't be used over std). And those languages make breaking changes! C++ is mostly stable, so it's full of junk like <regex> or just unordered_map. Rust managed to wholesale reimplement HashMap 6 months after SwissTable released, like it is also easier to express this level of encapsulation, but that's part of countless design/interface decisions made deliberately to not constrain forwards compatibility, including a smaller std.
However, that's no excuse to have a worse developer experience in this area. We need better tools to vet and communicate the quality of a crate and its supply-chain, like community-curated or even additional org-maintained crates, and maybe a handful delivered precompiled in the default rustup distribution which can change over time. I don't think they need to be added to std itself though
kibwen 6 hours ago
The idea that Rust has a small standard library is a weird meme. Rust has an enormous standard library. Look at any Rust release and you'll see dozens of new library APIs added, and consider that Rust has about nine releases a year, meaning that Rust adds over a hundred APIs per year, and has consistently for the past ten years. Rust frequently adds things that obviate popular crates, most recently the cfg_if crate was made redundant by the new cfg_select macro. And half of every dependency graph that people wrong their hands over are actually first-party external crates provided by either the Rust organization itself or by known contributors to the project. When people say that Rust has a small standard library, mostly they seem to just mean that it doesn't include a webserver.
bel8 5 hours ago
It still lacks basic functionality like a JSON parser, regex, directory walker, rnd generator and cli arg parsing.
I won't mention lack of date/time lib because that's complex and changes often.
That's why projects end up with 100s of crates, sometimes 1000s.
This might not be a well received fact in Rust community, but it's a fact nonetheless.
bilkow 3 hours ago
christophilus 7 hours ago
Rust seems barely better than Node in this regard. Go or .Net or anything with a robust standard library seems like the way to go for most projects.
ajross 6 hours ago
Cargo (and PyPI) is undeniably better than NPM, which is just shockingly bad for cultural reasons. Yet it's not safe, and it's subject to the same class of exploit, as we're seeing.
Indeed, the solution is to get away from the wild soup of author-managed dependencies and go with something with an audited collection of software that is maintained by separate human beings from the known-vulnerable hackers writing the software.
And indeed Go and .NET and Java all qualify. But the gold standard here is Debian and all its downstreams.
nicoburns 6 hours ago
> the solution is to get away from the wild soup of author-managed dependencies and go with something with an audited collection of software that is maintained by separate human beings from the known-vulnerable hackers writing the software.
I think we might be able to crowdsource audits. At least in the Rust ecosystem I'm confident that this is feasible with the right tooling.
rcxdude 6 hours ago
fnoef 6 hours ago
Oh, so it's not only "JavaScript bad and npm bad". Apparently, if your language uses third party dependency registry, you are prone to malicious code, regardless if it's Javascript or not.
Use containers for development. And reduce the amount of third party deps you import into your projects. This is only going to get worse.
patmorgan23 6 hours ago
Pulling in lots of dependencies creates this kind of risk regardless of the ecosystem. That being said in the JS/NPM world you tend to have a LOT more dependencies (especially indirect ones) than other languages. I saw someone do a cursory analysis and JS/Node projects tend to have 5x the number rust or ruby projects.
This is really a cultural problem not a technical one.
frollogaston 2 hours ago
It's funny how left-pad was always brought up as a JS supply chain vuln when that wasn't even malware
insanitybit 6 hours ago
If it weren't a registry it would be ./configure scripts and makefiles. The issue is that sandboxing technology is kinda shit (especially x-plat) and languages don't build it in by default.
xdavidliu 3 hours ago
> The genuine arrayref and append-only-vec crates are maintained by droundy, whose account appears to have been compromised.
That name looked familiar to me; I believe it's the same David Roundy who was an academic at Reed College who wrote DARCS, which is version control software. I used DARCS when I started grad school around 2010 before switching to git.
demibabs 7 hours ago
What does the malicious code actually do?
hmry 5 hours ago
I would like to know too, but the author's Github account seems to have been deleted, and the crates.io releases have been completely deleted too (not just yanked) so it seems impossible to view the file :/
FartyMcFarter 5 hours ago
Yeah I scanned the article and I couldn't find this either.
aselimov3 6 hours ago
Rust finally got hit... This was motivating me to swap away from Rust towards because of the huge number of dependencies. It seemed inevitable. Ginger bill was right, https://www.gingerbill.org/article/2025/09/08/package-manage...
jooops1 5 hours ago
The author proposes to reinvent the wheel and depend on stale dependencies, which are EOL. Neither of that is an acceptable solution with LLM-based Agents being able to produce exploit(ExploitGym) chains in minutes from known bugs. The other issue is that Rust's forces the user to provide more information and APIs are usually kept generic for systems programmer, so standardizing things is not as straight-forward compared to Go where you can assume a memory-management, a virtual thread runtime and mostly ignore dynamic dispatching.
aselimov3 2 hours ago
I don't think anyone is saying that you should depend on stale dependencies. You should not hand off your responsiblity to untrustworthy package managements services though. Evidence of the failure of automated package management is the near constant shai-hulud attacks as well as the originating post here.
The fact is that your dependencies are your responsibility. You should be staying up to date on what you depend on and their vulnerabilities. Most vulnerabilities affect specific code paths which may not be present in your code base and do not require mitigation. These are decisions you can make by understanding what your dependencies are instead of offloading to automated package management systems.
NPM has been the posterchild of these types of issues but the dependency stack I saw everytime I compiled even simple programs in Rust made me think Rust would be impacted next. Personally I think third party modules that are effectively universally used (axum, tokio, serde) should be integrated directly into the language.
Ygg2 6 hours ago
Honestly, Ginger Bill is plain wrong.
Just because you don't develop a package manager for your language, doesn't mean someone else won't. See NPM.
aselimov3 2 hours ago
Well I think the main important argument here is you shouldn't use the package management. A third party package manager would be even more concerning to use imo. I generally try to stay away from the typescript world so unfamiliar with nuances of NPM.
beanjuiceII 5 hours ago
yep which people have already done in odin
never_inline 5 hours ago
I am surprised this took so long.
aftbit 7 hours ago
Why do none of these hijacks embed runtime attacks? It seems like worming the build machines is the goal, rather than compromising downstream users.
It seems like we should be building and testing everything in bubblewrap or some other sandbox going forward.
Retr0id 7 hours ago
It usually takes some time for an updated dependency to actually get shipped to users in a release, by which time there's a good chance the attack has been noticed.
crote 6 hours ago
> Why do none of these hijacks embed runtime attacks? It seems like worming the build machines is the goal, rather than compromising downstream users.
Developer machines are quite juicy targets. They tend to have all sorts of credentials lying around, so it often isn't too difficult to escalate from that to compromising AWS/GCP/etc.
On top of that there's very little preventing a compromise. Developers are inherently expected to run untrusted code, and the usual Linux / MacOS laptop probably isn't even running any kind of anti-virus protection. Want to compromise the downstream app? Now you also need to pass Play Protect & friends.
> It seems like we should be building and testing everything in bubblewrap or some other sandbox going forward.
Yes, we really should. It is frankly a miracle that it has taken so long for fetch-time / install-time code execution to start blowing up in our faces. If we are spending so much effort on run-time isolation, why are we completely ignoring all those practices during development?
ptx 5 hours ago
Why are developers "inherently expected to run untrusted code"? Running untrusted code on developer machines seems like a terrible idea, given that it will compromise everything they build or deploy and (as you mentioned) all their credentials.
never_inline 5 hours ago
How do we know they don't? Who is going to read the source for all these micro packages?
You might assume we are able to detect all malicious behavior at runtime. But "stuxnet" and more recently, the xz compromise say otherwise. What if a not-so-popular crate deep in the dependency chain subtly introduced a LPE in it's code?
hsaliak 5 hours ago
At least it’s safe
dematz 6 hours ago
Jumping off the title and ignoring contents of post, as is customary: look at this graph and guess which languages use each number of dependencies for their website: https://www.youtube.com/watch?v=E82ly38YEEQ&t=325s
I won't spoil the claim in the video about what the dependency number is correlated with, and I'm not even sure how true it is in general, but it's very interesting.
somerandomness an hour ago
wow, what did payload do?
vlovich123 7 hours ago
I’m disappointed crates.io doesn’t have a stricter bar for serving a crate that has newly acquired a proc macro or build.rs. That seems like a trivial mitigation.
weinzierl 6 hours ago
Mitigation for what?
Compromising the code that is then most likely run in a test instead of compromising a build script is just a very slight inconvenience for the attacker.
I'm not particularly fond of arbitrary build scripts either, but restricting them will not help the supply chain issue in a significant way.
Also there are several ways to control build.rs execution in the Cargo ecosystem, for example with cargo-deny.
vlovich123 6 hours ago
Defaults matter. It’s nice you can set this up using a plugin to protect yourself, but that doesn’t protect the ecosystem, most of which doesn’t use cargo deny.
I also disagree a build scripts is a mild convenience. A build script always runs for anyone it’s a dependency for with full access and context and often has access to secrets in CI. A compromised runtime has more limited access and requires actual invocation of code paths (if you’re lying as a dependency that’s never executed, no exploit).
Of course Rust should have language-level support for capabilities so that just invoking a function doesn’t grant it access to arbitrary disk access. But that’s a much more difficult change than tweaking the defaults for cargo.
praseodym 6 hours ago
As mentioned by others it’s just as easy for an attacker to modify a crate’s runtime code.
vlovich123 6 hours ago
So? Runtime code requires actually executing the malicious code path which isn’t an immediate 100% hit rate for everyone that includes it in the dependency chain. For build.rs it’s a 100% compromise of everyone it’s in the dependency chain for. Additionally, at runtime you may not have access to secrets whereas at build time you most certainly do.
dgrunwald 2 hours ago
FartyMcFarter 5 hours ago
This is quite the egg on the face, given that Rust proponents keep telling us how it's great for writing secure software.
colingauvin 2 hours ago
I hate cargo and npm. Why do we keep settling on arbitrary code execution in our build process?
freakynit 8 hours ago
ahh... we now have nodejs ecosystem attack techniques migrating to other systems as well...
pixl97 6 hours ago
It's not very surprising as the node attacks were very effective at gathering credentials.
kunalsin9h 5 hours ago
damn!
acje 5 hours ago
I got to watch this attack unfold pretty much in real time as my agents worked the issue. Here is my writeup https://acje.github.io/systems/watching_a_supply_chain_attac...
Panzerschrek 7 hours ago
Why this still happens? Why after many previous supply-chain attacks maintainers of package repositories still allow anyone uploading packages and pushing updates without security audit?
surajrmal 7 hours ago
Who is funding this security audit? Are folks supposed to volunteer their free time? It's a difficult coordination problem. The best folks have come up is to delay adopting new releases by a few days and hope your dependency is popular enough that a security firm audits it for you in that timespan. If you have enough money I suppose you can start employing llms to audit things for yourself.
renox 6 hours ago
> It's a difficult coordination problem.
Well, it depends on the language: language which "capabilities" (both for the source code and for the building* ) could in theory really reduce a lot of the burden to identify supply chain attacks.
*: some research language have/had capabilities which would make supply chain attack "obvious" but for build systems I don't know if this exist.
bcjdjsndon 7 hours ago
> Who is funding this security audit? Are folks supposed to volunteer their free time?
Same people who keep the whole rust project going, a lot of those are volunteers aren't they? Not mad to think they could do the same for core packages at least
aw1621107 6 hours ago
nicoburns 6 hours ago
mirashii 6 hours ago
Panzerschrek 6 hours ago
Languages like Rust have sources of income to be able to finance such audit.
You don't need to audit all the crap is being uploaded right now. Only really necessary and widely-used packages should be managed in a centralized way, so, auditing all of them isn't that huge task.
weinzierl 6 hours ago
Mozilla, Google and a couple of others are publishing their audits through cargo vet. There are also additional audits done by individuals you can use through cargo crev. Overall the number of audited crates is in the thousands and you will find audits for most of the popular crates.
In the end it is your decision to use unaudited or refuse unaudited crates.
Panzerschrek 6 hours ago
> In the end it is your decision to use unaudited or refuse unaudited crates.
It should be the default behavior of the package manager to allow downloading only audited/trusted packages. Forcing end-users of the language to be responsible for audit of all dependencies is impractical.
weinzierl 6 hours ago
ecshafer 6 hours ago
These very small dependencies that are then later causing issues either due to malicious nature or incompetence, have become pervasive in computing (for some reason). I think that these should be less of an issue now than ever. Outside of the largest, most critical dependencies, you really shouldn't be pulling in small libraries anymore. Just generate the code via AI. AI is not great at large scale programming I think, but its amazing at snippets of code. Something I ran into recently, I needed to use FFT2 on some matrices, and what I was using didn't have an existing solution. Converting some numpy fft2 tests to my target language, and having a full native implementation of fft2, and an accompanying test suite so it will behave exactly like numpy fft2. A few minutes and a few thousand lines of code later, I have a trusted implementation. Saves me an external dependency, some weird glue code, and an attack vector.