Remix.run Logo
cxr 5 hours ago

At this point, the existence of these attacks should be an expected outcome. (It should have been expected even without the empirical record we now have and the multiple times that we can now cite.)

NPM and NPM-style package managers that are designed to late-fetch dependencies just before build-time are already fundamentally broken. They're an end-run around the underlying version control system, all in favor of an ill-considered, half-baked scheme to implement an alternative approach to version control of the package manager project maintainers' devising.

And they provide cover for attacks like this, because they encourage a culture where, because one's dependencies are all "over there", the massive surface area gets swept under the rug and they never get reviewed (because 56K NPM users can't be wrong).

stefan_bobev 4 hours ago | parent | next [-]

I am slowly waking up to the realization that we (software engineers) are laughably bad at security. I used to think that it was only NPM (I have worked a lot in this ecosystem over the years), but I have found this to be essentially everywhere: NPM is a poster child for this because of executable scripts on install, but every package manager essentially boils down to "Install this thing by name, no security checks". Every ecosystem I touch now (apart from gamedev, but only because I roll everything myself there by choice) has this - e.g Cargo has a lot of "tools" that you install globally so that you get some capability (like flamegraphs, asm output, test runners etc.) - this is the same vulnerability, manifesting slightly differently. Like others have pointed out, it is common to just pull random Docker images via Helm charts. It is also common to get random "utility" tools during builds in CI/CD pipelines, just by curl-ing random URLs of various "release archives". You don't even have to look too hard - this is surface level in pretty much every company, almost every industry (I have my doubts about the security theatre in some, but I have no first hand experience, so cannot say)

The issue I have is that I don't really have a good idea for a solution to this problem - on one hand, I don't expect everyone to roll the entire modern stacks by hand every time. Killing collaborative software development seems like literally throwing the baby out with the bath water. On the other hand, I feel like nothing I touch is "secure" in any real sense - the tick boxes are there, and they are all checked, but I don't think a single one of them really protects me against anything - most of the time, the monster is already inside the house.

Muromec 4 hours ago | parent | next [-]

>The issue I have is that I don't really have a good idea for a solution to this problem - on one hand, I don't expect everyone to roll the entire modern stacks by hand every time. Killing collaborative software development seems like literally throwing the baby out with the bath water.

Is NPM really collaborative? People just throw stuff out there and you can pick it up. It's the least commons denominator of collaboration.

The thing that NPM is missing is trust and trust doesn't scale to 1000x dependencies.

Jarwain 3 hours ago | parent | prev | next [-]

Something that I keep thinking about is spec driven design.

If, for code, there is a parallel "state" document with the intent behind each line of code, each function

And in conjunction that state document is connected to a "higher layer of abstraction" document (recursively up as needed) to tie in higher layers of intent

Such a thing would make it easier to surface weird behavior imo, alongside general "spec driven design" perks. More human readable = more eyes, and potential for automated LLM analysis too.

I'm not sure it'd be _Perfect_, but I think it'd be loads better than what we've got now

Cyph0n 4 hours ago | parent | prev | next [-]

I think the solution is a build system that requires version pinning - options include Nix, Bazel, and Buck.

stefan_bobev 4 hours ago | parent [-]

I am a big fan of Bazel and have explored Nix (although, regrettably not used it in anger quite yet) - both seem like good steps in the right direction and something I would love to see more usage/evolution of. However, it is important to recognize that these tools have a steep learning curve and require deep knowledge in more than one aspect in order to be used effectively/at all.

Speed of development and development experience are not metrics to be minimized/discarded lightly. If you were to start a company/product/project tomorrow, a lot of the things you want to be doing in the beginning are not related to these tools. You probably, most of the time, want to be exploring your solution space. Creating a development and CI/CD environment that can fully take advantage of these tools capabilities (like hermeticity and reproducibility) is not straightforward - in most cases setting up, scaling and maintaining these often requires a whole team with knowledge that most developers won't have. You don't want to gatekeep the writing of new software behind such requirements. But I do agree that the default should be closer to this, than what we have today. How we get there - now that is the million dollar question.

nicoburns 3 hours ago | parent | prev [-]

IMO the solution is auditing. We should be auditing every single version of every single dependency before we use it. Not necessarily personally, but we could have a review system like Ebay/Uber/AirBnB and require N trusted reviews.

ryandrake 2 hours ago | parent [-]

This is the way. But people read it, nod their heads, and then go back to yolo'ing dependencies into their project without reading them. Culture change is needed.

montroser 4 hours ago | parent | prev | next [-]

I agree with much of what you said here, but is it really just about the package manager? If I had specified this repo's git url with a specific version number or sha directly in my package.json, the outcome would be just about the same. And so that's not really an end-run around version control at that point. Even with npm out of the picture the problem is still there.

Gigachad 3 hours ago | parent [-]

The root problem is the OS allows npm packages to grab your WhatsApp messages without the user knowing.

wincy 3 hours ago | parent [-]

This is an npm package that allows you to interact with WhatsApp using their API. The OS wouldn’t prevent this as it’s not interacting with your WhatsApp on your machine, but rather logging you in via a skillfully made 3rd party interface, that unfortunately happens to also be evil.

josephg 4 hours ago | parent | prev | next [-]

> They're an end-run around the underlying version control system

I assume by "underlying version control system" you mean apt, rpm, homebrew and friends? They don't solve this problem either. Nobody in the opensource world is auditing code for you. Compromised xz still made it into apt. Who knows how many other packages are compromised in a similar way?

Also, apt and friends don't solve the problem that npm, cargo, pip and so on solve. I'm writing some software. I want to depend on some package X at version Y (eg numpy, serde, react, whatever). I want to use that package, at that version, on all supported platforms. Debian. Ubuntu. Redhat. MacOS. And so on. Try and do that using the system package manager and you're in a world of hurt. "Oh, your system only has official packages for SDL2, not SDL3. Maybe move your entire computer to an unustable branch of ubuntu to fix it?" / "Yeah, we don't have that python package in homebrew. Maybe you could add it and maintain it yourself?" / "New ticket: I'm trying to run your software in gentoo, but it only has an earlier version of dependency Y."

Hell. Utter hell.

__MatrixMan__ 4 hours ago | parent [-]

...unless your system package manager is nix.

bix6 4 hours ago | parent [-]

What is so special about nix that it avoids all these issues?

metaltyphoon 3 hours ago | parent | next [-]

Unless someone is vetting code, nothing.

2 hours ago | parent [-]
[deleted]
root_axis 3 hours ago | parent | prev | next [-]

nix is designed to support many versions of your dependencies on the same system by building a hash of your dependency graph and using that as a kind of dependency namespace for the various applications you have installed. The result is that you can run many versions of whatever application you want on the same system.

__MatrixMan__ 3 hours ago | parent | prev [-]

> Nobody in the opensource world is auditing code for you

That's still true of nix. Whether you should trust a package is on you. But nix solves everything else listed here.

> I want to use that package, at that version, on all supported platforms...

Nix derivations will fail to build if their contents rely on the FHS (https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html), so if a package tries to blindly trust that `/bin/bash` is in fact a compatible version of what you think it is, it won't make it into the package set. So we can each package our a bash script, and instead of running on "bash" each will run on the precise version of bash that we packaged with it. This goes for everything though, compilers, linkers, interpreters, packages that you might otherwise have installed with pip or npm or cargo... nix demands a hash for it up front. It could still have been malicious the whole time, but it can't suddenly become malicious at a later date.

> ... Debian. Ubuntu. Redhat. MacOS. And so on. Try and do that using the system package manager and you're in a world of hurt.

If you're on NixOS, nix is your system package manager. If you're not, you can still install nix and use it on all of those platforms (not Windows, certain heroic folk are working on that, WSL works though)

> Oh, your system only has official packages for SDL2, not SDL3. Maybe move your entire computer to an unustable branch of ubuntu to fix it?"

I just installed SDL3, nix put it in `/nix/store/yla09kr0357x5khlm8ijkmfm8vvzzkxb-sdl3-3.2.26`. Then I installed SDL2, nix put it in `/nix/store/a5ybsxyliwbay8lxx4994xinr2jw079z-sdl2-compat-2.32.58` If I want one or the other at different times, nix will add or remove those from my path. I just have to tell nix which one I want...

    $ nix shell nixpkgs#sdl2-compat
    $ # now I have sdl2
    $ exit
    $ nix shell nixpkgs#sdl3
    $ # now I have sdl3
> "Yeah, we don't have that python package in homebrew. Maybe you could add it and maintain it yourself?"

All of the major languages have some kind of foo2nix adapter package. When I want to use a python package that's not in nixpkgs, I use uv2nix and nix handles enforcing package sanity on them (i.e. maps uv.lock, a python thing, into flake.lock, a nix thing). I've been dabbling with typescript lately, so I'm using pnpm2nix to map typescript libraries in a similar way.

The learning curve is no joke, but if you climb it, only the hard problems will remain (deciding if the package is malicious in the first place).

Also, you'll have a new problem. You'll be forever cursed to watch people shoot themselves in the foot with inferior packaging, you'll know how to help them, but they'll turn you down with a variant of "that looks too unfamiliar, I'm going to stick with this thing that isn't working".

WD-42 4 hours ago | parent | prev [-]

I think you missed the mark a bit here. This wasn’t a dependency that was compromised, it was a dep that was malicious from the start. Package manager doesn’t really play into this. Even if this package was vendored the outcome would have been the same.

cromka 4 hours ago | parent [-]

No, package manager actually DOES play into this. Or, rather, the way best practices it enforces do. I would be seriously surprised if debian shipped malware, because the package manager is configured with debian repos by default and you know you can trust these to have a very strict oversight.

If apt's DNA was to download package binaries straight from Github, then I would blame it on the package manager for making it so inherently easy to download malware, wouldn't I?