Live data from Hacker News

Malicious code in the purescript NPM installer

harry.garrood.me

251–260 of 279 posts

Re: Malicious code in the purescript NPM installer

#251
post #2

I wonder how bad will this cred-stuffing package authors problem will get before npm/other package managers flat out require 2FA for maintainers

I'm not really familiar with how NPM packages are published - is it just referencing a commit hash in a repo, or is it a separate upload direct?

If it's the former (or could be made to be the former), requiring GPG signed commits would go a long way to preventing malicious activity.

Re: Malicious code in the purescript NPM installer

#252

Earlier quoted context omitted.

See, .NET get a lot of hate from the open source community, but this reason is one of the big ones of why I prefer it. Even when you compare it to Java, I feel like it's way better in this regard. If I want to work with JSON, I use Newtonsoft.JSON. If I want an ORM I'll use Dapper (lightweight) or Entity Framework. So many libraries that would you need if you're using Java or JS is just built in to the standard libra…

> I know it's not a 100% fair comparison, since I am biased. It might also have something to do with you apparently unironically comparing a framework to a programming language.

I'm not sure that you understand what .NET is. .NET is a platform/ecosystem. I was talking about packages. Packages are managed by nuget, which works across all .NET languages, which is why I didn't specify a language.

Re: Malicious code in the purescript NPM installer

#253
post #206
post #59

Earlier quoted context omitted.

Namespaces would be a feature of Crates.io, not Cargo (and Crates.io was not contracted to Yehuda Katz, as Cargo was).

How so? Do you mean that Cargo would support crates with names like "example/foo" or "org.example/foo", but that's just not how Crates.io works? If so, that's interesting, but then my question is why we didn't make use of that.

There's a few different elements of the design space. But, while Cargo can use crates.io, it's distinct from it, so on first principle, this would be a crates.io feature.

That being said, Cargo would also have to understand it, because the Rust language does not understand namespaced external packages, so you'd either have to change the language, or change Cargo to do something to paper over that somehow.

As for "why didn't we do this in the first place with crates.io", https://internals.rust-lang.org/t/crates-io-package-policies... lays out some of this background, though not all of it.

Re: Malicious code in the purescript NPM installer

#254
post #16

Before "tree shaking" I stored all npm modules in SCM and reviwed all updates as I had to commit after "npm update". I also put ton of files in .ignore as 90% of files in some packages are not required. I also used to include npm modules in distribution/deployment. So my request to npm is to add an option in the main package.json to disable tree shaking.

I wish there was a way to "bless" packages when they were reviewed. I want a network of trust, such that a Google reviewed package is worth 10 points, a package fuzzed by foobar is worth 2 points, something skimmed by a dependant user is worth 1 point etc. I can then chose a compromise between a highly rated/reviewed dependencies and functionality/risk/cost-to-review. My own blessing of a package I have reviewed migh…

I would not at all trust a "Google" reviewed package, not for their penchant privacy violations and writing code to fuel them.

Re: Malicious code in the purescript NPM installer

#255
post #172
post #24

Earlier quoted context omitted.

Perl (cpan), Python (pip or conda), Ruby (gem), and Rust (cargo) all behave as NPM does, so that doesn't seem to be the explanation here.

> Perl (cpan), Python (pip or conda), Ruby (gem), and Rust (cargo) all behave as NPM does Wrong. None of them have chosen the "micro-package" way of NPM. None of them have an average size of "3-10" line of code per package, which NPM has for many MANY packages. Cargo, pip have many packages but "reasonnable size" packages. ( > 100 lines ). The Micro-package philosophy that NPM chose, meaning every single line of code…

Nobody is closing their eyes and singing "everything is fine." A large number of small packages is a good thing, and a technically strong ecosystem supports it. Having spent the last week in the internals of glibc chasing bugs in code that has no reason to be jammed into the same library that handles initial program loading, I can attest that there are good, justifiable, technical reasons to do things the NPM way, and I'm glad that there are smart, qualified, talented people implementing that.

I know it's hard for you to imagine, but perhaps the JavaScript ecosystem has some good things about it.

Re: Malicious code in the purescript NPM installer

#256
post #206

Earlier quoted context omitted.

How so? Do you mean that Cargo would support crates with names like "example/foo" or "org.example/foo", but that's just not how Crates.io works? If so, that's interesting, but then my question is why we didn't make use of that.

There's a few different elements of the design space. But, while Cargo can use crates.io, it's distinct from it, so on first principle, this would be a crates.io feature. That being said, Cargo would also have to understand it, because the Rust language does not understand namespaced external packages, so you'd either have to change the language, or change Cargo to do something to paper over that somehow. As for "why…

Thanks for the reference!

> When we looked at package ecosystems without namespacing, we found that people tended to go with more creative names (like nokogiri instead of “tenderlove’s libxml2”). These creative names tend to be short and memorable, in part because of the lack of any hierarchy. They make it easier to communicate concisely and unambiguously about packages. They create exciting brands.

I will never stop admiring your ability to see the bright side of things.

Re: Malicious code in the purescript NPM installer

#257
post #54

Earlier quoted context omitted.

I trust these people to manage software packages: https://nm.debian.org/public/people/dm_all They “only” manage ~18K packages, but those 18K do a lot more than NPM: https://people.debian.org/~corsac/ perhaps number of packages is the wrong metric.

> but those 18K do a lot more than NPM This is so hilariously wrong it's actually shocking it was written?

Indeed. I looked through the Debian packages and didn't see left-pad anywhere.

Re: Malicious code in the purescript NPM installer

#258
post #56

Earlier quoted context omitted.

A lot of those packages are going to be versions months or sometimes years behind the latest version. I'm not convinced this is a model that can work for programming libraries.

You may be correct for javascript, whose ecosystem is notoriously unstable and the equivalent of "building on sand". eg write some code in a JS framework, then go off and do something for 18 months. Come back and there's a very good chance the entire framework has been obsoleted and replaced, perhaps even several times. In JS land that's "Doh, well of course!". In sane ecosystems (eg not Ruby), not so much. ;)

This is a problem for _any_ active development package, to the point where most language communities have (previously had) instructions on how to fix breakage of the language introduced by, for example, arbitrary Debian packaging restrictions without working with the language maintainers.

I seen this in _any_ environment that has a relatively active package management system of its own (e.g., Ruby, Perl, and Python included)—and it _still_ happens in some Java cases. The only _sane_ thing to do is to completely ignore the OS package management system and to package your applications as relocatable install packages complete with all dependencies you need, modulo the minimal OS stuff required.

Re: Malicious code in the purescript NPM installer

#259
post #176

Earlier quoted context omitted.

As a thought experiment: Assume Rubygems chose to operate in that way, where all gems must be owned by a group rather than an individual user. Then, assume that the most flexible option is for each gem to be owned by a unique group: that way even if two gems are maintained by the same users right now, they use two distinct groups in case that ownership changes in the future. We might as well just name the “group” the…

> Assume Rubygems chose to operate in that way, where all gems must be owned by a group rather than an individual user. Sorry, this wasn't my premise -- I meant to have this as an option . As in / or /project>. > Then, assume that the most flexible option is for each gem to be owned by a unique group: that way even if two gems are maintained by the same users right now, they use two distinct groups in case that owner…

OK, let's walk through how the scenario you lay out works in the context of a package graph.

I have my_app, which depends on foo and bar. Both of those use purescript. My app calls into foo which gets some object created from the purescript library and returns it. I then pass that object to bar. For this to work gracefully, they need to have a shared dependency on the same purescript.

(purescript is a weird example to use here, but imagine the shared dependency is a library that provides something like a reusable data structure.)

What happens to my_app when purescript gets passed from group-a to group-b? If foo wants to be on the latest, they need to move over to group-b. But if they do that and bar doesn't, then my_app can't get the latest version of foo. The foo and bar maintainers know that, which means they know they have a disincentive to move over to group-b. Better to stay on group-a and keep things moving smoothly with their existing users.

You end up in a situation where the choice that is better for a single package in isolation (move to the latest version of a dependency) is harmful to the package in context (it breaks shared dependencies and prevents users from upgrading to your latest version).

This is one of the most important situations to avoid when designing a package manager. As much as possible, you want to give package maintainers the freedom to evolve their package without it destabilizing the ecosystem. There's an argument that this is fundamentally what a package manager is — a tool to let you reuse changing code. If you don't need to evolve the code being reused, then FTP is a perfectly sufficient package manager.

Enshrining ownership in the package name directly confounds that. And, like another comment suggests, if you do that, maintainers will just route around it by creating an "organization" for each package, putting you right back where you started.

Re: Malicious code in the purescript NPM installer

#260
post #171

Earlier quoted context omitted.

> It's just infinitely, obviously better. Whenever a large number of skilled people do something for which an alternative is "infinitely, obviously better", there's a good chance that there is more going on than you know. RubyGems used to be namespaced this way and moved away from it. They didn't do so lightly. The problem is that ownership, and even names of owners change all the time . In the very very large majori…

But every change of ownership is a potential mass security compromise.

Every change period is. There's no guarantee that the same owner (individual or group) won't spontaneously go rogue and introduce harmful changes.

This is why modern package managers have lockfiles and give you control over when you upgrade any package version, regardless of ownership change. Ultimately, you are responsible for the code you reuse.

Post reply on HN