Live data from Hacker News

Malicious code in the purescript NPM installer

harry.garrood.me

191–200 of 279 posts

Re: Malicious code in the purescript NPM installer

#191
post #187

Earlier quoted context omitted.

...wow. I literally did not believe that until I clicked the link. JavaScript has gone too far.

well, the rate-map at least includes a function: https://github.com/sindresorhus/shebang-regex

A dependency for /^#!(.*)/;

With 8.6 mil downloads and 71 dependents...

https://www.npmjs.com/package/shebang-regex

Re: Malicious code in the purescript NPM installer

#192

Another reminder of how annoying it is for a package system to have unqualified package names. Having to ask someone to gift a `purescript` package shouldn't even be a thing. It should've been `@shinn/purescript` and the compiler developers just create their own `@whatever/purescript`. This is something Elm and many others got right. https://package.elm-lang.org/ It's just infinitely, obviously better. You see all so…

> 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…

When package owners change, or change names, would the original package namespace still stick around for all the existing versions? Also, would there be a pointer built in that let you know about the new owner namespace when you try to upgrade automatically?

If so, I really don't see the practical problem. Actually it seems like useful information. If I'm upgrading and the package owner changed, that's definitely something I want to at least be told so I can look into whether that's important depending on the usecase. In that sense, it is a potentially breaking change. Particularly from a security standpoint.

If it's not the case, and everything including the version history is ported over to the new namespace and you're simply forced to change stuff just to get it working again, I agree this is just pointless churn.

Re: Malicious code in the purescript NPM installer

#193
post #176

Earlier quoted context omitted.

It seems like a reasonable fix to this is to prevent name-specific owning (changing it to a group instead) -- this has the benefit that package maintainers who plan to maintain their packages forever can keep the same names, and those that don't can essentially fork their project and stop fixing the older version (@ / ) and force all changes to go to a new one (@ / ) and hand off ownership as necessary. This doesn't…

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 ownership changes in the future.

> We might as well just name the “group” the same as the gem name, since only one gem is managed by each group. So now the “purescript” group maintains “purescript”, the “pry” group maintains “pry”, etc.

I don't agree -- even if it's always group-a/purescript I think the distinction is still important, because in this case previous-group/puresecript still exists, but is frozen/archived. Here's how I'm understanding the scenario you laid out:

1. group-a/purescript is created

2. purescript changes ownership, group-b is going to be publishing it going forward

3. group-b/purescript is created

4. group-a/purescript freezes/archives/deprecates itself

5. group-b/purescript is actively developed

The fact that "group-b" is the "right" purescript is arbitrary/subjective to some degree.

> I think there’s a pretty compelling case that package managers should support group ACLing on publishing (giving multiple humans the first-class right to publish using individual creds to a group namespace, with the ability to add/remove users from the group over time. But once you’ve done that, the distinction between explicit group-name-in-package-path and changing-name-to-fork (so the difference between fork-group/orig-name and orig-name_fork-group) seems to shrink.

I think these two issues are a bit separate. Letting people dynamically change who owns/can publish to a repository is one way to solve this problem, but I think it's more complex than the fork-and-move approach.

IMO if some user wants to give up/transfer their repo, they:

1. find someone else to take over if they want

2. freeze/archive/whatever their repo

3. let the person fork & continue their work

An ownership change should be opt in, unless it was known @ package creation time that ownership would be a shared/rotated/changing/nebulous thing (which would be demonstrated by a group owning the package from the beginning).

Re: Malicious code in the purescript NPM installer

#194

Earlier quoted context omitted.

It seems like a reasonable fix to this is to prevent name-specific owning (changing it to a group instead) -- this has the benefit that package maintainers who plan to maintain their packages forever can keep the same names, and those that don't can essentially fork their project and stop fixing the older version (@ / ) and force all changes to go to a new one (@ / ) and hand off ownership as necessary. This doesn't…

You could go farther and use a DNS name as a group name, then publish packages by signing with the SSL key. Anyone who doesn't want to shell out for a domain name could use a registry service that gives subdomains out. Why reinvent the governance wheel?

I'd agree, but I don't think the additional complexity is worth it. I was prepared to suggest stuff like company.com/

That said, it's worked well for golang as far as I can see, despite 99% of the packages are github.com//.

Here are some writeups on what the rust team decided:

- https://github.com/rust-lang/crates.io/issues/58

- https://internals.rust-lang.org/t/crates-io-package-policies...

Their stance seems pretty reasonable though I'm not sure I would have done the same (and it's obviously very likely I would be wrong to do the opposite of what they did):

> Namespacing

> In the first month with crates.io 58, a number of people have asked us aboutthe possibility of introducing namespaced packages 90.

> While namespaced packages allow multiple authors to use a single, generic name, they add complexity to how packaged are referenced in Rust code and in human communication about packages. At first glance, they allow multiple authors to claim names like http, but that simply means that people will need to refer to those packages as wycats' http or reem's http, offering little benefit over package names like wycats-http or reem-http.

> 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. And we’ve seen the success of several 10,000+ package ecosystems like NPM and RubyGems whose communities are prospering within a single namespace.

> In short, we don’t think the Cargo ecosystem would be better off if Piston chose a name like bvssvni/game-engine (allowing other users to choose wycats/game-engine) instead of simply piston.

> Because namespaces are strictly more complicated in a number of ways,and because they can be added compatibly in the future should they become necessary, we’re going to stick with a single shared namespace.

Re: Malicious code in the purescript NPM installer

#195
post #188
post #182

Earlier quoted context omitted.

> None of them have chosen the "micro-package" way of NPM. This is not something inherent to npm itself, it's what the people using npm choose to publish. No matter if people like small modules or not, it's not at all related to the topic discussed.

> No matter if people like small modules or not, it's not at all related to the topic discussed. It is very relevant to the topic discussed. Just for fun : https://npm.anvaka.com/#/view/2d/purescript > 150 dependencies. Including a package named "one-time", bundled several times in two different versions. To do something highly relevant and technical like "Call a function once". I have no doubt that it is an Highly c…

Thank you for linking to that dependency grapher.

The crab-grass like dependencies of many/most NPM packages is scary enough, and then they (or you?), I guess because of lazy loading, to improve responsiveness, update it as you watch.. It's like a scene out of an alien monster movie, where the creature keeps growing more limbs.

Re: Malicious code in the purescript NPM installer

#196
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…

I wasn’t implying you claimed that all gems needed a group, I was proposing it as part of the thought experiment. My apologies if that was unclear.

To your list of examples: my point parallels your own, I think. I’m saying that given the “right” version is arbitrary and subjective, the difference between “group-b/purescript” and “purescript-group-b” is effectively nil. More concretely: if namespacing existed, you could fork “group-a/purescript” to “group-b/purescript”, but if namespacing didn’t, you could fork “purescript” to “purescript-group-b”. In either case, dependent projects need to update where they source their dependencies from.

Namespacing, in my experience, tends to make the forking process slightly “cleaner”, because you avoid having a potentially non-“right” “original” (for example, “purescript” tends to look more legitimate than “purescript-group-b”). But some comments in this thread seem to paint namespacing as a hard requirement, or claim that package managers without namespacing are missing a core, mandatory feature. The case I’m presenting is that this isn’t the case: namespacing is a useful feature for several workflows, but adding namespacing doesn’t fundamentally alter the issue.

Re: Malicious code in the purescript NPM installer

#197
post #191
post #187

Earlier quoted context omitted.

well, the rate-map at least includes a function: https://github.com/sindresorhus/shebang-regex

A dependency for /^#!(.*)/; With 8.6 mil downloads and 71 dependents... https://www.npmjs.com/package/shebang-regex

and if you look closely, 70 of those dependents are just small-scale/bs packages and the only sensible real dependency is cross-spawn _via_ the shebang package (which applies this regex to a string). The whole ecosysten could use a purge of all those useless 1-line-requires (which were all introduced by helpful commits from the "i has 1337 downloads"-community), currently this is madness.

Re: Malicious code in the purescript NPM installer

#198

Earlier quoted context omitted.

I actually built something like this a few months ago. I called it “OSSassin” (like the game[1]) so devs could sign up & get a unique ID/url to ping with the idea that everyone participating would then try to secretly, and not maliciously, “assassinate” the packages that have agreed to participate by sneaking in code to ping their endpoint. Just as a fun/friendly game to help identify potential vulnerabilities. It ha…

That sounds like a really fun gamification of an aspect of security research that maybe doesn't get much practical exploration. I'm not sure, though, how the game would distinguish between vulnerable code pinging the endpoint, as opposed to a player simulating a successful attack by performing the ping themselves. I feel like the attacker should be able to provide a link to a package on a software repo somewhere and…

That was a wonderful story, this seems to be the source, but your storytelling makes it better.

https://mobile.twitter.com/Sc00bzT/status/730903007014076416

https://news.ycombinator.com/item?id=11691798

Re: Malicious code in the purescript NPM installer

#199

Earlier quoted context omitted.

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…

You may find npms.io[1] useful. For each package, they provide a score on maintainability, popularity and quality. [1] https://npms.io

npms.io rates the `rate-map` package with quality 99%, so not sure how helpful that is

Re: Malicious code in the purescript NPM installer

#200
post #196

Earlier quoted context omitted.

> 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…

I wasn’t implying you claimed that all gems needed a group, I was proposing it as part of the thought experiment. My apologies if that was unclear. To your list of examples: my point parallels your own, I think. I’m saying that given the “right” version is arbitrary and subjective, the difference between “group-b/purescript” and “purescript-group-b” is effectively nil. More concretely: if namespacing existed, you cou…

> I wasn’t implying you claimed that all gems needed a group, I was proposing it as part of the thought experiment. My apologies if that was unclear.

My apologies I certainly misread your comment.

> To your list of examples: my point parallels your own, I think. I’m saying that given the “right” version is arbitrary and subjective, the difference between “group-b/purescript” and “purescript-group-b” is effectively nil. More concretely: if namespacing existed, you could fork “group-a/purescript” to “group-b/purescript”, but if namespacing didn’t, you could fork “purescript” to “purescript-group-b”. In either case, dependent projects need to update where they source their dependencies from.

I agree -- the effects are definitely similar and almost equivalent. However does requiring a group/author change things at all? It seems like it could introduce an abstraction lever.

> Namespacing, in my experience, tends to make the forking process slightly “cleaner”, because you avoid having a potentially non-“right” “original” (for example, “purescript” tends to look more legitimate than “purescript-group-b”). But some comments in this thread seem to paint namespacing as a hard requirement, or claim that package managers without namespacing are missing a core, mandatory feature. The case I’m presenting is that this isn’t the case: namespacing is a useful feature for several workflows, but adding namespacing doesn’t fundamentally alter the issue.

I'm on the fence -- I'm not sure if this is a good counter case, but what about the layer of abstraction introduced by the implied/required existence of ? You could write code that imports "purescript", but then resolve it later (as some others mentioned, go.mod is or some other modules file that clarifies mappings) to determine which "purescript" that is. You could solve this by "alias"ing "project/purescript" to "purescript" (and then having some similar extra configuration that says "purescript" -> "project/purescript", and now I'm not sure if either is better (so basically having this indirection be a "module resolution feature" or a "module aliasing feature"), and if there's any value in forcing one (requiring the existence of would almost certainly force the module resolution thing, but also break builds the second similarly named packages were published...) or if they really are just the same.

I also found the page on this by the rust team pretty convincing[0].

[0]: https://internals.rust-lang.org/t/crates-io-package-policies...

Post reply on HN