logoalt Hacker News

nananana9today at 5:54 AM14 repliesview on HN

Package managers are a failed experiment.

We have libraries like SQLite, which is a single .c file that you drag into your project and it immediately does a ton of incredibly useful, non-trivial work for you, while barely increasing your executable's size.

The issue is not dependencies themselves, it's transitive ones. Nobody installs left-pad or is-even-number directly, and "libraries" like these are the vast majority of the attack surface. If you get rid of transitive dependencies, you get rid of the need of a package manager, as installing a package becomes unzipping a few files into a vendor/ folder.

There's so many C libraries like this. Off the top of my head, SQLite, FreeType, OpenSSL, libcurl, libpng/jpeg, stb everything, zlib, lua, SDL, GLFW... I do game development so I'm most familiar with the ones commonly used in game engines, but I'm sure other fields have similarly high quality C libraries.

They also bindings for every language under the sun. Rust libraries are very rarely used outside of Rust, and C#/Java/JS/Python libraries are never used outside their respective language (aside form Java ones in other JVM langs).


Replies

pjc50today at 6:41 AM

Package managers are now basically a requirement for language adoption. Doing it manually is not a solution, in an automated world.

What is a problem is library quality. Which is downstream of nobody getting paid for it, combined with an optimistic but unrealistic "all packages are equal" philosophy.

> High quality C libraries

> OpenSSL

OpenSSL is one of the ones where there's a ground up rewrite happening because the code quality is so terrible while being security critical.

On the other end, javascript is uniquely bad because of the deployment model and difficulty of adding things to the standard library, so everything is littered with polyfills.

show 1 reply
staticassertiontoday at 12:18 PM

They're not a failed experiment. No one has ever "experimented" by making a safe package manager for their new language. And it is not that insane to do so. Very basic things will get you very far:

1. Packages should carry a manifest that declares what they do at build time, just like Chrome extensions do. This manifest would then be used to configure its build environment.

2. Publishers to official registries should be forced to use 2FA. I proposed this a decade ago for crates.io and people lost their minds, like I was suggesting we drag developers to a shed to be shot.

3. Every package registry should produce a detailed audit log that contains a "who, what, when". Every build/ command should be producing audit logs that can be collected by endpoint agents too.

4. Every package registry should support TUF.

5. Typosquatting defenses should be standard.

etc etc etc. Some of this is hard, some of this is not hard. All of this is possible. No one has done it, so it's way too early to say "package managers can't be made safe" when no one has tried.

show 1 reply
hvb2today at 6:11 AM

If you're developing for the web your attack surface is quite a bit bigger. Your proposed solution of copying a few files might work but how do you keep track of updates? You might be vulnerable to a published exploit fixed a few months ago. A package manager might tell you a new version is available. I don't know how that would work in your scenario.

show 1 reply
doginasuittoday at 10:41 AM

> We have libraries like SQLite, which is a single .c file that you drag into your project and it immediately does a ton of incredibly useful, non-trivial work for you, while barely increasing your executable's size.

I'm not sure why you believe this is more secure than a package manager. At least with a package manager there is an opportunity for vetting. It's also trivial that it did not increase your executable's size. If your executable depends on it, it increases its effective size.

layer8today at 6:43 AM

For some reason, NPM is the only ecosystem with substantial issues with supply-chain attacks.

show 4 replies
allreducetoday at 7:47 AM

I don't think this community of professionals is going to come around to a solution which requires marginally more effort.

If no one checks their dependencies, the solution is to centralize this responsibility at the package repository. Something like left-pad should simply not be admitted to npm. Enforce a set of stricter rules which only allow non-trivial packages maintained by someone who is clearly accountable.

Another change one could make is develop bigger standard libraries with all the utilities which are useful. For example in Rust there are a few de facto standard packages one needs very often, which then also force you to pull in a bunch of transitive dependencies. Those could also be part of the standard library.

This all amounts to increasing the minimal scope of useful functionality a package has to have to be admitted and increasing accountability of the people maintaining them. This obviously comes with more effort on the maintainers part, but hey maybe we could even pay them for their labor.

squeaky-cleantoday at 4:30 PM

SQLite had 6 CVE's last year. FreeType had an RCE bug published last year. libcurl's last CVE reported was 2 weeks ago. Libpng had 4 vulnerabilities published this year....

vincnetastoday at 6:47 AM

no no, please we don't want to get back to dragging files to your project to make them work.

show 1 reply
voidfunctoday at 6:17 AM

I'd really like to see package managers organized around rings where a very small core of incredibly important stuff is kept in ring 0, ring 1 gets a slightly wider amount of stuff and can only depend on ring 0 dependencies and then ring 2+ is the crapware libraries that infect most ecosystems.

But maybe that's not the right fit either. The world where package managers are just open to whatever needs to die. It's no longer a safe model.

show 3 replies
pie_flavortoday at 7:15 AM

Rust libraries are infrequently used outside of Rust because if you have the option, you'd just use Rust, not the ancient featureless language intrinsically responsible for 70% of all security issues. C libraries are infrequently used in Rust outside of system libc, for the same reason; I go and toggle the reqwest switch to use rustls every time, because OpenSSL is horrendous. This is also why you say 'rarely' instead of 'never', when a few years ago it was 'never'; a few years from now you'll say 'uncommonly', and so on. The reason C libraries are used is because you don't feel like reimplementing it yourself, and they are there; but that doesn't apply more to C libraries than Rust libraries, and the vast majority of crates.io wouldn't be usefully represented in C anyway, or would take longer to bind to than to rewrite. (No, nobody uses libcurl.) Finally, this only happens in NPM, and the Rust libraries you pull in are all high-quality. So this sounds like a bunch of handwaving about nonsense.

show 1 reply
jonkoopstoday at 9:02 AM

> We have libraries like SQLite, which is a single .c file that you drag into your project

You are just swapping a package manager with security by obscurity by copy pasting code into your project. It is arguably a much worse way of handling supply chain security, as now there is no way to audit your dependencies.

> If you get rid of transitive dependencies, you get rid of the need of a package manager

This argument makes no sense. Obviously reducing the amount of transitive dependencies is almost always a good thing, but it doesn't change the fundamental benefits of a package manager.

> There's so many C libraries like this

The language with the most fundamental and dangerous ways of handling memory, the language that is constantly in the news for numerous security problems even in massively popular libraries such as OpenSSL? Yes, definitely copy-paste that code in, surely nothing can go wrong.

> They also bindings for every language under the sun. Rust libraries are very rarely used outside of Rust

This is a WILD assumption, doing C-style bindings is actually quite common. YOu will of course then also be exposing a memory unsafe interface, as that is what you get with C.

What exactly is your argument here? It feels like what you are trying to say is that we should just stop doing JS and instead all make C programs that copy paste massive libraries because that is somhow 'high quality'.

This seems like a massively uninformed, one-sided and frankly ridiculous take.

show 1 reply
TacticalCodertoday at 2:45 PM

Then you've got ecosystems like Clojure where many projects are just considered done and used by many. You can pin these (and be warned if a new version still comes out, say for an actual security fix). There are Clojure projects so stable, without any know exploit (we're certainly not talking about daily npm exploits here), that haven't been updated in years because they are... Done. Simply done. Perfection.

Something to reflect upon too.

victorbjorklundtoday at 9:25 AM

I think you can do copy paste in most languages. But it will be a pain to update when there are improvements / security fixes.

You got a project with 1-2 depencies? Sure. But if you need to bring in 100 different libs (because you bring in 10 libs which in turn brings in 10 libs) good luck.

show 1 reply
anthktoday at 12:17 PM

Package managers are older than some users here. From CPAN/CTAN to ports under BSD's.

Some pm's are badly maintained (Pip/NPM), while others are curated enough.

Again, if you have GNU/Linux installed, install Guix, read the Info manual on 'guix import' and just create a shell/container with 'guix shell --container' (and a manifest package created from guix import) and use any crap you need for NPM in a reproducible and isolated way. You $HOME will be safe, for sure.