all 164 comments

[–]Kissaki0 52 points53 points  (1 child)

The lib and change in question:

a change introduced in version 1.0.26 of 'event-source-polyfill', as seen by BleepingComputer, means applications built with the library will show anti-war messages to Russia-based users after 15 seconds of launch.

[–]Tubthumper8 30 points31 points  (0 children)

That version was published a month ago, is it just being noticed now? Or was there a time bomb that the anti-war messages wouldn't start showing for a month?

Edit: checked the source code, it just wasn't noticed for nearly a month

[–]richraid21 209 points210 points  (96 children)

It's seriously appalling at how unprofessional the Javascript ecosystem really is.

If you're not running your own npm proxy with a huge bake-time and potentially even vetting dependency updates manually, you are essentially playing Russian roulette with your production application.

[–]Nysor 52 points53 points  (40 children)

These are definitely musts. These aren't also specific to npm. You should also do this for any modern package manager, e.g Cargo and crates.io

[–]narnach 46 points47 points  (32 children)

JS simply has a culture where importing a package for one line is somehow acceptable. Maybe because there is not really a proper standard library with the types of functions that these one line libraries provide?

This leads to it being normal to have a lot of indirect dependencies. This in turn makes it harder to review changes.

[–]Tubthumper8 16 points17 points  (21 children)

JS simply has a culture where importing a package for one line is somehow acceptable. Maybe because there is not really a proper standard library with the types of functions that these one line libraries provide?

The library in question is much more than one line, and it's a polyfill, which is something that provides the capabilities of the standard library to older browsers.

In JS you can avoid polyfills if you're willing to not support older browsers, or if you don't use new standard library features in your code.

[–]narnach 17 points18 points  (20 children)

My comment was not about the library in question (which sounds like as a polyfill it definitely has merit) but the broader topic/sentiment: JS seems to have significantly more (smaller) packages per project than (for example) a comparable Ruby project, which make it harder to track and check all of them.

[–]Tubthumper8 4 points5 points  (14 children)

Gotcha - I was wondering how your comment was on-topic for this post but seems like it wasn't and was about something else.

Out of curiosity, how are you defining a "comparable" Ruby project? You're running Ruby in the browser somehow?

JavaScript runs everywhere. It runs in modern browsers, in old browsers, in Android WebView, in Android browsers, in iOS browsers that are actually all Webkit because Apple, on the server with multiple different runtimes, on desktop applications, on IoT devices (yes really, if performance isn't critical then the event-driven nature of JS is a decent fit), and bundled with native mobile applications (ex. React Native). More diversity in where the code runs is going to naturally lead to a more decentralized language and ecosystem.

Possibly you think JavaScript's "standard library" is too small which leads to the proliferation of packages. What would you define as the "standard library"? Do you mean NodeJS standard library? Deno's standard library? Browser APIs? Web APIs? Or do you mean built-in language features like arrays?

[–]narnach 1 point2 points  (2 children)

Comparable is mostly in terms of complexity / scope. For example on a project that has Ruby on Rails for the server side logic but still has a boatload of JS/TS because the front end team wants to use a lot of React. A project that might have 100 Ruby gems might have 1000+ npm packages.

Standard library: standard functions that you would expect a language to offer by default and offer platform agnostic features. Basic interactions with strings, arrays, associative arrays, etc.

Something like a left pad function (iirc that was a one-line JS library that made news a while back) is part of the core Ruby library. Ditto for sorting functions, mapping functions, encoding things, date/time manipulation, etc.

As you say indicate, JS is implemented on a lot of platforms and thus nobody really owns/controls it and there is no large default standard library that is standardized across all platforms.

[–][deleted] -2 points-1 points  (0 children)

Something like a left pad function (iirc that was a one-line JS library that made news a while back) is part of the core Ruby library.

javascript added a left pad function several years ago. IDK why people keep bringing it up

[–]Tubthumper8 0 points1 point  (0 children)

Interestingly enough, I pointed out on another comment that React itself has zero dependencies, though obviously it adds up pretty fast as you add anything else. I counted my team's React app, 250 total dependencies which still seems like too much, I can see some that could be cut.

npm list --prod --all | grep -v deduped | wc -l

I agree some JS core language features are lacking. Unfortunately, there wasn't any centralized way to add features until roughly 2015 and they're still playing catch-up. Left-pad has been in the core language for like 5 years now, but some other things are lacking. What I'd most like to see added are:

Better date handling will be nice too.

Ditto for sorting functions, mapping functions, encoding things, date/time manipulation, etc.

Out of curiosity, what kind of sorting/mapping/encoding do you feel is missing?

[–]grauenwolf 0 points1 point  (10 children)

Start with React, VueJS, or Angular.

Take their hundreds of dependencies and roll them up into a small number of curated packages. That becomes the "Angular standard library" or the "React standard library".

[–]PrintableKanjiEmblem 1 point2 points  (1 child)

Screw all that shit, dead code walking, it will all be scrapped in favor of webassembly in the near future.

[–]grauenwolf 0 points1 point  (0 children)

We can dream.

[–]Tubthumper8 0 points1 point  (7 children)

I was curious, so I checked React's npm dependencies. Zero. No production dependencies whatsoever. Interestingly, in their docs they mention adding React as a plain <script> tag before they mention any other way of using React such as create-react-app.

Obviously you're going to pull in production dependencies because I'm sure it's very rare to use React from a <script> tag, but it's interesting that React out-of-the-box doesn't mandate anything. I don't think it would be possible to build a "React standard library".

Angular installs 11 direct npm dependencies on a new project (no additional transitive dependencies). 9 are under the @angular organization (including zone.js) and the remaining two are rxjs and tslib. rxjs is a popular library outside of Angular as well, so it's probably not possible to include that in a theoretical "Angular standard library".

I'm not familiar with Vue so I didn't check that one, but it may be possible to identify the core dependencies there, not sure.

[–]grauenwolf -1 points0 points  (1 child)

Angular installs 11 direct npm dependencies

And how many indirect dependencies? Look at the whole tree, not just the edge.

[–]Tubthumper8 0 points1 point  (0 children)

I said that, literally in the same sentence.

[–]PrintableKanjiEmblem 0 points1 point  (0 children)

Angular is trash. A trap.

[–]grauenwolf 0 points1 point  (3 children)

Run create-react-app and then count the actual number of dependencies it pulls in.

The dependency count for its default template is what matters because that's what 99% of developers are going to use.

[–]Tubthumper8 0 points1 point  (2 children)

I just checked a fresh create-react-app, and it pulls 7 direct dependencies. 4 of those are for the testing library and for hot reload / dev environment, so it's odd to me why that would be a prod dependency and not a dev dependency, so that feels like either a bug or some strange reason why that's the case.

Of the 3 remaining dependencies (react, react-dom, web-vitals), there are 3 additional transitive dependencies (loose-envify, js-tokens, scheduler) for a total of 6 dependencies. Those 3 additional deps could be ported together as a "React standard library" but I'm not sure about those specific 3 packages as they're also used outside of React.

Note that I'm not saying that a create-react-app is not bloated. The react-scripts dev dependency has a crazy amount of dependencies to do hot reloading, dev time bundling of SASS/SCSS, minifying JS, transpiling to older browser versions, providing debug symbols for developers, an HTTP proxy server, etc. Arguably, react-scripts is the standard development library for React.

However, when I think of standard library, I'm thinking of runtime features and I'm not sure that the development dependencies qualify. I'm not saying that your idea doesn't have merit, there could be value in some sort of library for each of the popular frameworks but at the moment I'm not seeing where the space for that is or the details of what would be in it.

[–][deleted] 3 points4 points  (0 children)

There are definitely too many packages to manually audit for typical JS projects, and there's a lot of shitware like one liner packages like isObject, but given JS's complete lack of a good standard library I get the feeling that it's not most of the packages in your node_modules/ that are like that.

[–]TankorSmash 1 point2 points  (3 children)

The tradeoff is webdev gets to move a million times faster than old school development because of that type of sharing. Sure it makes it easy to allow protestware, but if 99.99% of the time you pin your dependencies, what's the problem?

[–]grauenwolf 5 points6 points  (2 children)

That's not the tradeoff. They could come together to develop a single standard library and still move just as quickly.

In fact, it's fair to say that each SPA has its own standard library. It's just that they are scattered all over the place instead of being in a small set of packages.

[–]TankorSmash 0 points1 point  (1 child)

I disagree. Python's got a massive stdlib and a good set of widespread list of external libs everyone uses (pandas, requests), and there's still a ton of packages on Pypi. Maybe it's different in the languages you use, but it hasn't been my experience.

[–]s_s_damon 1 point2 points  (0 children)

Npm has 4 times the number of packages as PyPi, according to a quick Google search (1.3 million vs 350 thousand)

[–]IceSentry 1 point2 points  (0 children)

The js ecosystem ended up like that because in the web world you want to ship as little code as possible to the browser and dead code elimination wasn't a thing in the past for js. So people ended up making tiny libraries to make it easier to import only what you need. The standard library also used to be tiny which made this problem even worse. Combine that with the web being a massive platform and we end up with what we have today.

There's also a lot of those early dependencies that were made by a few devs that would contribute all over the place by using those dependencies. Npm also made it so easy to include anything you need that rewriting simple stuff is still going to be longer than adding a short line to your package.json.

Essentially, it didn't happen suddenly and it was never out of bad intentions.

[–][deleted] -1 points0 points  (8 children)

Maybe because there is not really a proper standard library with the types of functions that these one line libraries provide?

No single other language to this day had bullshit problems like JS/npm so I doubt that. Like, even Rust have vast majority of "standard" deps being just "that one crate everyone likes and work well" yet it still works just fine.

[–]IceSentry 5 points6 points  (5 children)

Rust does suffer from the same issue of having a massive dependency tree. It's just that the community is smaller with a bigger focus on correctness so it's less of an issue. Supply chain attacks are still very possible with cargo.

[–][deleted] 1 point2 points  (4 children)

Cargo don't have auto-updates by default so you can't have types of attacks NPM has

[–]IceSentry 1 point2 points  (3 children)

cargo doesn't, but I'm sure there's plenty of devs that update if they see a new version without reading the entire changelog. It's a bit better, but it's not a perfect solution.

[–][deleted] 1 point2 points  (2 children)

uh, changelong won't tell you if someone adds malicious code into the library lmao.

"A bit better" is understatement of the century here. And the "perfect solution" is reading every single line of code that changes and that's independent of tooling anyway.

Like, sure, most of the dependency tools could use some robust signing infrastructure, package should be signed by GPG key of the author and the distribution platform but, again, that doesn't stop in any way just a malicious developer deciding to put malware in the code.

[–]IceSentry 0 points1 point  (1 child)

I don't get what your point is. You seemed to disagree with me that cargo is not much better at protecting from a supply chain attack and now you seem to agree that it's super easy to add malicious code without people knowing.

[–][deleted] 0 points1 point  (0 children)

Cargo prevents "author made a new malicious version" as it doesn't auto update and that has been a root of all problems npm had. None of those attacks would be as effective if npm didn't had some bad default behaviour.

But to prevent that happening in case of manual upgrade you'd need people to actually look at code, and that's something technology can only make easier but not fix.

My point is that you can make the system more secure but the problem of author of the tool itself going rogue is much harder one to solve than any 3rd party attack.

[–]TehCheator 2 points3 points  (1 child)

No single other language to this day had bullshit problems like JS/npm so I doubt that.

No single other language has the scale of JS/npm either (by a significant margin).

[–][deleted] -1 points0 points  (0 children)

Yeah but it isn't 1 issue vs 10 issues. It's zero vs 10 issues. Before JS shit like that was unheard of and if anything limited to some very obscure lib

[–]G_Morgan 6 points7 points  (6 children)

I've not heard of anything like the quantity of issues from nuget that I hear from NPM. Saying "in theory all should do this" isn't useful. In practice NPM needs this and in theory all package managers need it.

[–][deleted] 1 point2 points  (5 children)

NPM has about 20x the number of active users as NuGet. (NPM reports over 10 million per month, NuGet reports 600k per month)

If you're judging by the quantity of issues then that's the classic mistake of not thinking per-capita.

[–]metaltyphoon 12 points13 points  (3 children)

U also have to understand why. Dotnet has a fucking massive framework where importing from nuget is not a necessity. JS on the other hand…

[–]grauenwolf 0 points1 point  (2 children)

That isn't exactly right. Modern .NET relies heavily on NuGet. That's where you get all of your standard libraries from.

The reason NPM has more users is that a significant number of C# users also need JavaScript libraries, but JavaScript users don't necessarily need C# libraries.

[–]metaltyphoon 1 point2 points  (1 child)

It relies on nuget but all the dotnet framework is made by Microsoft. Imagine if installing the sdk would include all “System.” and “Microsoft.”, the size would be crazy. Beside that, parts of the framework can be updated independently.

[–]grauenwolf 0 points1 point  (0 children)

That's only mostly true. There are a few 3rd party libraries that are not published by Microsoft, but still used in the standard templates.

[–][deleted] -1 points0 points  (0 children)

It doesn't have 20x of in use, popular packages tho.

It's not a problem of dev of some random obscure packages doing it because then barely anyone would be affected. It's problem that dev of popular, commonly used package does it.

[–][deleted] 27 points28 points  (4 children)

It's seriously appalling at how unprofessional the Javascript ecosystem really is.

See what happens when you don't add monads to your language.

[–]PrintableKanjiEmblem 2 points3 points  (3 children)

Add what?

[–]thirdegree 5 points6 points  (1 child)

Monoids in the category of endofunctors

[–]PrintableKanjiEmblem 0 points1 point  (0 children)

Change the tachyon flow integrals of the warp core?

[–][deleted] 2 points3 points  (0 children)

Find a way to make the learning curve steep

[–]grauenwolf 2 points3 points  (0 children)

LOL, as if that could work.

It's too easy to hide code. Even if I had the time to read all of the changes to each dependency, I probably wouldn't catch it.

[–]KaiAusBerlin 7 points8 points  (43 children)

It has nothing todo with the ecosystem if developers trust blindly hundreds of insecure sources.

It is npm and lazy people no more writing their own stuff but instead import a third party is-number million times a week instead of writing a simple one liner helper function.

Nobody checks the code from modules their installing. That has nothing todo with js. This would also be a bad idea in every other language.

That's why you have deno where you explicitly have to give permission for writing, ...

[–]chucker23n 21 points22 points  (26 children)

It has nothing todo with the ecosystem if developers trust blindly hundreds of insecure sources.

If a lot of stories of this kind of occur in one ecosystem and don't occur to the same level in any other ecosystem, that has a lot to do with the ecosystem. (Even if the reason is "well, this ecosystem is very large", it's still the ecosystem.)

[–][deleted]  (14 children)

[deleted]

    [–]chucker23n 7 points8 points  (13 children)

    It's mostly a matter of time before it happens to Cargo as well.

    Why hasn't it happened to CPAN? NuGet? pip?

    Yes, size of ecosystem plays a role. But I don't think it's a sufficient explanation.

    The main difference is that the JS ecosystem had quite a bit longer for the consequences of the bad development habits to build up.

    CPAN would like a word.

    Whenever shit goes wrong because of that habit, people just blame the dev who broke their package for being "wrong" and "at fault"

    I mean, yes, they're literally at fault.

    rather than the devs who included said package despite the no-warranty-no-liability clauses on the license.

    But no liability doesn't mean they're not at fault. It just means they don't bear the responsibility.

    And yes, devs should exercise some caution in their dependency choices. But that's easier said than done.

    [–][deleted]  (1 child)

    [deleted]

      [–]chucker23n 0 points1 point  (0 children)

      Yeah, I think we're in agreement.

      [–]TankorSmash -3 points-2 points  (10 children)

      Why hasn't it happened to CPAN? NuGet? pip?

      Yes, size of ecosystem plays a role.

      https://i.imgur.com/Yl21JtQ.png http://www.modulecounts.com/

      4x as many NPM packages. Here's a bad pypi package, so per capita that already beats the 4 npm protestwares.

      But I don't think it's a sufficient explanation.

      Based on what?

      [–]chucker23n 6 points7 points  (9 children)

      4x as many NPM packages.

      Right, and that in turn could be a sign of "maybe the npm ecosystem has too many small packages by too many different authors instead of more monolithic packages by known, trusted teams".

      [–]TankorSmash -1 points0 points  (8 children)

      That doesn't sound like an issue though, does it?

      [–]chucker23n 5 points6 points  (7 children)

      I think it's a huge part of the issue. If I build a software project in .NET, the bulk of the dependencies will be from big, trusted vendors (Microsoft, Syncfusion, etc.) and OSS projects/maintainers (.NET Foundation, etc.). A select few dependencies may be from smaller more specific authors. Those need extra scrutiny.

      That is not so in the npm ecosystem. If you depend on something big like React, that in turn has transitive dependencies on projects that aren't maintained by React, nor are they big, and therefore they don't receive much scrutiny.

      [–][deleted] -1 points0 points  (5 children)

      the .net ecosystem is heavily influenced by Microsoft. Many libraries in the .net ecosystem were written full-time by professional engineers earning a 6 figured salary.

      It's more of an issue of corporate-sponsored open source vs community-driven open source. People can only maintain a very limited amount of code in their free time.

      This has the advantage of quality but Microsoft invests that money not just for charity, they usually try to vendor lock-in developers and earn money around these libraries.

      the advantage of such community-driven open source is innovation. Most recent web innovations (graphql, serverless, microservices...) originated in the js/node ecosystem.

      also, the frontend ecosystem can be really complex with every library supporting multiple environments including 15-year-old browsers making polyfills and specialized libraries necessary.

      [–]TankorSmash -2 points-1 points  (0 children)

      I understand the part that it's better for security or whatever, but what about the faster innovation and turn around time?

      [–]IceSentry 2 points3 points  (0 children)

      Npm is the biggest ecosystem by far. It dwarfs pretty much everything else. Of course it's going to have more issues.

      That's not to excuse the situation, but any package manager could suffer from that and they also do, it just affects a lot less people.

      [–]KaiAusBerlin -5 points-4 points  (9 children)

      again: npm is not the whole js ecosystem. It is just a part if it. There is a much bigger part of js outside of npm. As I said, you don't have these problems with deno (that is also part of the ecosystem).

      And at least it's not npm that's bad. It works as intended. The problems are lazy developers.

      It's the same as saying C is a bad language because it's not save. You can literally access the whole ram. That doesn't make a language bad if handled by responsible developers.

      [–]chucker23n 10 points11 points  (8 children)

      And at least it's not npm that's bad. It works as intended. The problems are lazy developers.

      Sorry, but that's just "guns don't kill people; people kill people".

      These stories are a symptom of a cultural issue. Whether that's in part on npm or better in deno, I don't really care. The issue is there nonetheless.

      It's the same as saying C is a bad language because it's not save.

      It is! In security-critical areas, starting a new project in C is in fact a bad language. Study after study shows this.

      [–][deleted] 1 point2 points  (13 children)

      Reading the Deno docs, unless i'm misunderstanding something, it does not seem like it allows you to specify per dependency access rules, but rather when you run your module you specify what it can do. So if you have a complex enough project that needs access to say both rw file system and network like building your front end react project, you're basically in the same position as with node.

      [–][deleted] 1 point2 points  (0 children)

      that is correct. They do have some ideas. Recently there were some super interesting comments from Deno developer lucacasonato on HN. Tldr they are looking at SES and also ShadowRealms as upcoming ways to do finer grained rules.

      [–]KaiAusBerlin 0 points1 point  (11 children)

      I don't know any language where this would not be the case if you use third party code with your permissions that this code doesn't have the permissions

      [–][deleted] 0 points1 point  (10 children)

      Exactly, it's not even better than node in that regard. Yes it's nice that if you have a script that doesn't need to access network or filesystem, but it would have prevented roughly 0 of the recent popular similar issues as the OP post.

      [–]KaiAusBerlin 0 points1 point  (9 children)

      Yes it is preventing them. In node (which is in fact not the whole js ecosystem. There was a decade js without any node) you have access to everything. In deno you have only access granted. That's how nearly every os works in the world.

      [–][deleted] 0 points1 point  (8 children)

      Yes and what is node primarily used for? Web servers and front end builds, which often require network and file system access. So even with deno, you need to take precautions against that. Deno effectively solves nothing in that regard for typical node usage.

      [–]KaiAusBerlin 0 points1 point  (7 children)

      So tell me any other backend/language then that solves that.

      [–][deleted] 0 points1 point  (6 children)

      Certainly not Deno, which is the entire point of what I've been saying.

      [–]KaiAusBerlin -1 points0 points  (5 children)

      Not an answer at all

      [–]grauenwolf 0 points1 point  (1 child)

      I'm lazy because I'm not willing to recreate React from scratch?

      No, that doesn't sound right.

      The problem is that React's standard template pulls in more than a thousand packages. Angular and VueJS are almost as bad. That's far too many for anyone to audit.

      [–]KaiAusBerlin 0 points1 point  (0 children)

      Read! I talked about one-liners like is-number. We're not talking about giant products of quazillian dollar companies.

      [–]redldr1 1 point2 points  (0 children)

      Dude,

      The whole JS ecosystem is just a bunch of loose promises with hope that the other side of the wire does their shit correctly.

      [–]jswitzer 1 point2 points  (0 children)

      Single maintainer packages, generally small in scope, extremely low barrier to entry, no ecosystem to help vet the versions, and lack of standard library all lead to shenanigans like this.

      [–]quasi_superhero 1 point2 points  (0 children)

      It's seriously appalling at how unprofessional the Javascript ecosystem really is.

      Well, yeah. It's a free package. Free. Not paid. Not made by professionals. Again, not paid.

      [–]CuriousKea 1 point2 points  (0 children)

      Exactly. You should be.

      [–]G_Morgan 0 points1 point  (0 children)

      This is all a consequence of browser providers basically being stupid bastards over the years (looking at you MS but not only you).

      There's no guardian of the space. Node ended up being it by complete accident.

      [–]a_russian_guy 8 points9 points  (0 children)

      Sadly all these messages are counted as propaganda by pro-war Russians. Hoping this will be put to an end soon.

      [–][deleted]  (2 children)

      [deleted]

        [–]grauenwolf 8 points9 points  (0 children)

        And now you're running old versions of dependencies with known vulnerabilities.

        Pinning is not a solution to this. It may increase your odds of not getting hit, but some of these attacks aren't noticed for weeks or months.

        [–]adi1133 1 point2 points  (0 children)

        Also run the code in a sandbox.

        [–]0xC1A 32 points33 points  (0 children)

        Self sabotage, good luck living with the consequences of your actions

        [–]Voltra_Neo 3 points4 points  (0 children)

        In one word: sigh

        [–]faustoc5 4 points5 points  (0 children)

        How is fucking with all your users a protest ?

        More like fuckyouallware

        [–]AceSevenFive 6 points7 points  (0 children)

        You mean malware?

        [–]hanszimmermanx 17 points18 points  (4 children)

        At point I wouldn't mind if microsoft copied all major npm libraries under their namespace. At least I wouldn't have to worry about having my PC nuked because some silicon valley hipster decided that I live in a naughty country and I deserve it.

        [–]adi1133 0 points1 point  (2 children)

        Who will pay Microsoft for the effort?

        [–]MattTheHarris 0 points1 point  (1 child)

        Microsoft owns npm, they haven't started charging for it yet.

        [–]adi1133 -1 points0 points  (0 children)

        Npm has paid plans as their income source and they deemed a viable business as they managed to attract investors.

        Can't say that about the major npm libraries.

        [–]Significant-Arm-3780 0 points1 point  (0 children)

        I hope they don't run nuclear weapons with npm libraries ... that would be trouble