|
|
Subscribe / Log in / New account

A single Node of failure

By Nathan Willis
March 30, 2016

The web-development community was briefly thrown into chaos in late March when a lone Node.js developer suddenly unpublished a short but widely used package from the Node Package Manager (npm) repository. The events leading up to that developer's withdrawal are controversial in their own right, but the chaotic effects raise even more serious questions for the Node.js and npm user communities.

npm itself is a module repository for Node.js code, akin to the Python Package Index or similar repositories for other languages and frameworks. Users can install a package with a simple npm install foo, but the service is also widely used by Node.js developers to automatically fetch and install dependencies: projects list their dependencies in the package.json file, and they are recursively fetched from npm and installed when the package is built. Using npm in this manner is standard operating procedure, allowing complex JavaScript applications to be written on top of multiple third-party frameworks in minimal lines of code. The service, however, is run by a private company called npm, Inc., rather than by the Node.js project.

Kik starter

The trouble began with Azer Koçulu's module kik, a command-line tool designed to ask a few simple questions and set up a new Node.js project template based on the answers. According to Koçulu, a lawyer representing Kik Interactive (makers of the Kik instant-messaging app) contacted him by email and insisted he change the name of the package. When he refused, the company took its demand to npm, Inc. instead, copying Koçulu on the emails. npm founder Isaac Z. Schlueter then took ownership of the kik module on npm from Koçulu and unpublished it, without Koçulu's consent.

That action, it seems, frustrated Koçulu to the point where he decided to pull all of his other packages from npm as well; in his post on the subject, he commented that the situation "made me realize NPM is someone’s private land where corporate is more powerful than the people" and "NPM is no longer a place that I’ll share my open source work at". He concluded by apologizing for any effect the move might have downstream:

This is not a knee-jerk action. I love open source and believe that open source community will eventually create a truly free alternative for NPM.

I’m apologize from you if your stuff just got broken due to this. You can either point your dependency to repo directly (azer/dependency) or if you volunteer to take ownership of any module in my Github, I’ll happily transfer the ownership.

The story might have ended there, except that Koçulu was the owner of quite a few modules on npm. And, as luck would have it, one in particular, called left-pad, was part of the dependency chain for a host of high-profile Node.js projects and frameworks—including React.js, Babel, and Ember.js. When left-pad disappeared from npm, it caused a chain reaction of dependency failures that broke scores of JavaScript project builds.

Although no major interruptions appear to have hit live services, the widespread breakage of automated builds caused considerable panic; Daphne Maddox now famously described the impact as "This kind of just broke the internet." Reacting to the outcry, npm's Laurie Voss restored the unpublished left-pad module to the repository. On Twitter, he commented that "Un-un-publishing is an unprecedented action that we're taking given the severity and widespread nature of breakage, and isn't done lightly." Later, he said that Koçulu's decision to pull left-pad from the repository "puts the wider interests of the community of npm users at odds with the wishes of one author" and that the restoration was made because "I cannot see hundreds of builds failing every second and not fix it."

npm later posted its account of the events, citing the service's package name dispute resolution policy as the rationale for removing Koçulu as the owner of the kik module name. It also defended the re-publishing of Koçulu's left-pad module, noting that most of the downstream builds inherited their left-pad dependency through the line-numbers package, which was hard-coded to depend on left-pad 0.0.3. Even though another developer (Cameron Westland) created a new left-pad module shortly after the original was pulled, the new module was numbered version 1.0.0, which did not fix most of the dependencies.

For its part, Kik also posted its side of the story, quoting from the emails exchanged between Koçulu and the company representative, who it notes is the company's patent agent and not a lawyer. The post expresses regret for the unfolding drama:

The wording we used here was not perfect. We’re sorry for creating any impression that this was anything more than a polite request to use the Kik package name on NPM for an open source project we have been working on that fits the name.

Interestingly enough, Kik's representative evidently told Koçulu that the company would "have no choice" but to take down his accounts "because you have to enforce trademarks or you lose them." That is a common enough refrain, although as attorney Pamela Chestek recently pointed out, the "defend it or lose it" idea is not actually part of US trademark law. How one interprets the email exchanges between Kik and Koçulu will, no doubt, vary. It does seem, however, that Kik sought a compromise of some sort; Koçulu quoted a buyout price, which Kik did not accept.

Although many who commented on the string of events were clearly upset at Koçulu, he had his share of supporters as well, in light of the naming dispute with Kik. Tom McGee, for instance, wrote on GitHub: "Forget my broken build, stick it to the man!!" The past week has also seen a flurry of new protest projects appear on npm, using the name kik or otherwise referencing left-pad.

Left behind

As to the widespread cascade of disruption caused by the missing left-pad module, the community voiced several concerns about how npm is managed. First, providing the ability to unpublish a module is controversial. In its blog post, npm cited "historical reasons" for retaining the feature, but many other package repositories simply do not make it possible to remove an existing release on which other code depends. Mozilla's E. Dunham, for instance, noted that the Crates.io repository used by Rust projects allows developers to "yank" a release, which prevents it from being added to new builds, but does not break existing dependency relationships.

Furthermore, npm's package-publishing rules created yet another bind in that, once pulled, no other developer could publish another left-pad module utilizing an already-used version number. Thus, even though Westland published his replacement left-pad module just a few minutes after the Koçulu unpublished the original, it could not satisfy the hard-coded version dependency in line-numbers. That limitation is what forced Voss to take the "unprecedented action" of undoing Koçulu's withdrawal of the 0.0.3 release.

As several of the initial commenters on GitHub bug reports noted, another problem with npm is that modules are not namespaced by origin or user account. That made it impossible for downstream projects to simply switch from Koçulu's left-pad package to Westland's.

But perhaps the broadest issue raised is that npm itself is not managed by the Node.js community. Instead, it is run by a private entity and not subject to oversight. Koçulu's departure stemmed directly from what he saw as npm management siding with a for-profit company to take away his access to his own work. Many of the supportive comments from other developers seemed to agree—either expressing discontent with npm's unilateral action, or concern that no agreed-upon policy seemed to be at work.

There are, after all, many existing modules available in npm that use names trademarked by someone in the software industry, from well-known brands like Facebook to more generic words like square. The developer behind the newly minted not-kik package even challenged npm on the point, describing it with: "It's not kik, and never will be. But it has kik in its name. What now, NPM Inc.?"

Bryan Cantrill suggested that the "inescapable conclusion" was that the npm registry should be managed by the Node.js Foundation. So far, that idea does not seem to have gained much traction.

Lazyweb

The other side to the debate is concern that such a simple module as left-pad was widely enough used in the first place to wreak so much havoc when it disappeared. The module was eleven lines long, and served only to left-pad strings. Surely, the argument goes, such a simplistic function is too small to demand its own package—or, better yet, its purpose is so simple that any developers worth their salt should have implemented it themselves in mere minutes.

David Haney provided an in-depth critique of the Node.js community on precisely those grounds, calling the left-pad catastrophe symptomatic of a "stringing APIs together and calling it programming" mindset in the npm ecosystem, with developers "writing the smallest amount of code possible to string existing library calls together in order to create something new that functions uniquely for their personal or business need."

He added: "What concerns me here is that so many packages took on a dependency for a simple left padding string function, rather than taking 2 minutes to write such a basic function themselves." While the sentiment was echoed elsewhere on various discussion forums, Node.js developers as a whole, it seems, did not take the criticism lightly. The second comment on Haney's post chided him for "fundamentally misunderstanding the npm ecosystem and small module philosophy". Whether that refutes or underscores Haney's argument seems to be largely a matter of perspective.

Apart from the effort it takes to write a string-padding function, many people have pointed out that the hard-coded version dependency in the line-numbers module is bad form in its own right. Furthermore, even when it was unclear whether or not left-pad 0.0.3 could be restored to the npm registry, many developers complaining about broken builds seemed unaware of the fact that there are other ways (outside of npm) to specify a dependency in a Node.js package. One could even have pointed directly at Koçulu's left-pad code on GitHub.

Node War II?

On March 29, npm announced that it would, indeed, be changing its module-unpublishing policy. In the new policy, authors have a 24 hour window in which a published version can be unpublished. After 24 hours, authors will have to contact npm's support team, who will check whether or not the removal will break any dependencies for other packages. Furthermore, if every published version of a module is unpublished, npm, Inc. will take over the package name to prevent "malicious squatting". The post calls the new policy "a first step towards balancing the rights of individual publishers with npm’s responsibility to maintain the social cohesion of the open source community". Time will tell how well it will be received by the Node.js community.

The kik/left-pad debacle hinged largely on version numbering and package naming, but the incident is far from the only criticism leveled at npm. For instance, Google's Sam Saccone found that npm module installation poses a significant security risk. The npm command-line tool allows downloaded packages to run scripts with the full privileges as the current user; this means that a malicious script hidden in a dependency might run arbitrary commands as a user (or even as root). Among the possibilities is that such a script could publish updates of the user's modules directly to npm, allowing it to spread as a worm.

Others, like Armin Ronacher, warn that npm's "micro-dependency" approach leaves open several other possible exploits, starting with a "dependency explosion" that creates more packages than a reasonable person can be expected to maintain with scrutiny. One individual developer, he noted, maintains 827 separate modules on npm. Even if they are small, he said, "it's significantly harder for him to ensure that all of those are actually his releases". As recent events have shown, even a small module can be the source of considerable trouble. The open question is whether or not npm—and the larger Node.js development community—will learn from this experience and be able to self-correct.


to post comments

A single Node of failure

Posted Mar 30, 2016 22:14 UTC (Wed) by roblucid (guest, #48964) [Link] (1 responses)

Bleh! ~snigger snigger~

While we're at it...

Posted Apr 1, 2016 20:37 UTC (Fri) by pboddie (guest, #50784) [Link]

"This kind of just broke the internet."

Not really. Maybe... "This kind of just broke the hipsternet."

Indeed, I only heard about this when Armin Ronacher blogged about it via, of all channels, Planet Python. At which point I was reminded that people had, maybe still have, a tendency to build "live" against the Python Package Index and delegate all control to the game of chance involving network connectivity, server availability, whether the package is still there, and so on. At least the Python Package Index people had a long-overdue discussion about package signing, however.

A single Node of failure

Posted Mar 30, 2016 23:37 UTC (Wed) by hummassa (guest, #307) [Link] (21 responses)

Am I interpreting the whole thing wrong, or are people complaining of "too much code reuse"??

A single Node of failure

Posted Mar 30, 2016 23:51 UTC (Wed) by asaz989 (guest, #67798) [Link]

You might very well think that. I couldn't possibly comment.

A single Node of failure

Posted Mar 31, 2016 0:05 UTC (Thu) by bronson (subscriber, #4806) [Link] (7 responses)

That's an oversimplification. If you're not careful, Node projects can result in a vertical tower of dependencies, where you spend as much time editing package.json than actual js files. Especially if you're returning to a project two years later.

A lot of these dependencies seems to be working around JavaScript's heinously incomplete standard library.

A single Node of failure

Posted Mar 31, 2016 0:10 UTC (Thu) by jberkus (guest, #55561) [Link] (3 responses)

Maybe the solution is to create a more complete standard library, then? I mean, the fact that JS doesn't have an lpad() function, but it had to be added by a solo developer, is pretty alarming.

A single Node of failure

Posted Apr 1, 2016 2:57 UTC (Fri) by smurf (subscriber, #17840) [Link]

The real failure appears to be one of "language culture". In most languages, you search for some way to achieve e.g. a left-pad function, you find the code on a Forum or Wiki page and you copy that to your local library of utility stuff, if not inlining it altogether.

With node.js, all you get is the name of the library to include, and I can only assume that people don't even look at the code they're including that way, most of the time.
When I search for something like that, I incorporate the principles involved directly into the code I'm working with instead of calling out. I like to think that this improves my understanding of what the hell I am doing. That opportunity is lost if you don't even look at the stuff.

A single Node of failure

Posted Apr 1, 2016 17:44 UTC (Fri) by lsl (guest, #86508) [Link]

I'm not so sure. Looking at other packages available on NPM it seems that even if Javascript had a sprintf (which is what lpad is called in most other languages) there would still be a package on NPM that just calls sprintf with the right arguments or so.

Heck, there's even a package "is-positive-integer" that depended on three other packages *and* made breaking API changes in the past! It's hard to believe this is not a joke.

A single Node of failure

Posted Jan 5, 2017 6:31 UTC (Thu) by Otus (subscriber, #67685) [Link]

> Maybe the solution is to create a more complete standard library, then?

Given the variety of runtimes code needs to run on that just amounts to pushing all such code into transpilers and polyfills.

Is it better to have fewer and larger dependencies? Not sure. It has its upsides, but there is no way I'm going to review such a massive codebase while small dependencies I can and have read through.

A single Node of failure

Posted Mar 31, 2016 0:12 UTC (Thu) by hummassa (guest, #307) [Link]

But there is only one problem: that npm allowed "unpublishing" of modules. You could always say "left-pad 4.0 is void" but the dependencies on left-pad 3.0 would still be there and no harm, no foul.

Not that I think JS is a good language or that it has a good standard library. It's just that npm is really lightweight and allowed those kinds of modules, that would then be integrated to the ecosystem. My CPAN and DarkPAN modules are minuscule, too.

A single Node of failure

Posted Mar 31, 2016 7:32 UTC (Thu) by marcH (subscriber, #57642) [Link] (1 responses)

> If you're not careful, Node projects can result in a vertical tower of dependencies, where you spend as much time editing package.json than actual js files

Maybe there should be some small, re-usable package.json bits that one could easily combine together...

A single Node of failure

Posted Mar 31, 2016 21:18 UTC (Thu) by bronson (subscriber, #4806) [Link]

Agreed. If only Node programmers could rely on a broad set of useful functions always being available, ...

A single Node of failure

Posted Mar 31, 2016 13:13 UTC (Thu) by tshow (subscriber, #6411) [Link] (9 responses)

> Am I interpreting the whole thing wrong, or are people complaining of "too much code reuse"??

The choice here is between (a) writing what ought to be a three line function at worst (calc length of padding, concat that many spaces together, concat string on the end), and (b) dragging in the arbitrary dependency graph of some micro-package to do it for you, while hoping both it and all its dependencies are both well written and available.

The moment you start depending on external packages, you open yourself up to version mismatches, packages getting unpublished, packages getting updated in ways incompatible with your code. Every once in a while, things will just break because of something done by someone you've never met, somewhere out there in the vast dark.

And part of the "reuse" here is eventually going to be security exploits, if it hasn't already. Looking at the way these dependency trees fan out, it would be trivial for someone to slip an exploit in to a commonly used micropackage somewhere way down in the weeds. With the complexity of the dep tree and the apparently cavalier attitude of "why write a couple of lines of code when I can use someone else's" happening at nearly all levels, we've got a security nightmare on our hands. Active exploits could lurk for years, because nobody is taking the time to validate all the code in the massive dependency fan-out.

And that's assuming that nobody making exploits is clever enough to obfuscate things using version trickery or DNS poisoning, or what have you. There's no way to security audit this.

A single Node of failure

Posted Mar 31, 2016 19:22 UTC (Thu) by samroberts (subscriber, #46749) [Link] (8 responses)

Right, because writing it yourself rather than using well-known libraries is good security practice?

With npm, if a package has a security vulnerability, then the package can be updated, and the security fix can be pulled in with a single update to all its dependencies. If you don't want that, shrinkwrap your projects, to pin the versions of your dependencies. Then you get to hear about how a security fix was released... but your app didn't get it.

A single Node of failure

Posted Mar 31, 2016 21:03 UTC (Thu) by ibukanov (subscriber, #3942) [Link]

There is a difference between a security bug and a deliberately put exploit. Npm model protects against the former as it makes it trivial to update after a bug is discovered via running a single command. The price for that is that it turns npm into a vehicle to deliver an exploit right into thousands of developers' computers.

Compare that with a model where all dependencies are explicitly copied into the source tree. Surely it makes it harder to upgrade especially if one manually applies patches for security bugs. But then one avoids exposure to deliberate exploits as the delivery is simply not there.

A single Node of failure

Posted Apr 1, 2016 13:17 UTC (Fri) by tshow (subscriber, #6411) [Link] (6 responses)

> Right, because writing it yourself rather than using well-known libraries is good security practice?

In this case? Absolutely. You're thinking about bugs when you should be thinking about the intentional addition of malicious code. What if instead of just left-padding, this code had left-padded but oh by the way checked to see if the input string looked like an email address and if so harvested it and sent it off to a spam server? Or kept a copy around in case it saw something that looked like a password string... Would anyone have noticed, until the maintainer pulled it and broke things?

These micro-packages are for things like left-padding strings and determining if something is an array. Trivial things. Things that are unlikely to cause security bugs even if badly coded, given we're talking about a garbage-collected language with proper string support.

And you aren't just using "well-known" libraries, you're using everything that their deptree drags in. THAT is the problem here; how many people who's projects broke were actually even aware that left-pad was a dependency? The "well-known" library they used dragged in a bunch of other possibly less-known libraries which in turn dragged in a bunch more even less known libraries, and pretty soon you have hundreds of dependencies, most of which are never going to see serious security scrutiny.

ANY one of those trivial sub-sub-sub-dependencies is a vector for malicious code insertion, because who'd ever find it? And with the way the deptree fans out, a bit of trivial social engineering and some patience in getting your not-yet-malicious-but-just-wait-'til-you-trust-me module worked into the system (or taking over as maintainer of an existing module that's well-connected but in a dark corner of the deptree) basically gives you everything using NPM on a platter.

This is not like (say) the Linux kernel, where there are tiers of reviewers to get past before you can get your malicious code in. Once a micropackage is trusted, it doesn't seem like there's any mechanism to check that the code does no more than it says on the label. Unit tests do nothing to check for side effects, and besides, unit tests can be malicious too.

So yes, writing it yourself is by far the better security practice here.

A single Node of failure

Posted Apr 1, 2016 16:24 UTC (Fri) by samroberts (subscriber, #46749) [Link] (5 responses)

I think this is a tempest in a teapot. Comparing this to the Linux tree, or debian packages is overkill, most webapps don't have that kind of control or review of their dependencies, in any language.

Compare it instead to a Rails app, something in the same application space. The situation here is:

1. node app with 400 dependencies, many of them small
2. rails app with 20 dependencies, most of them large

Assume total code size would be aproximately the same for an app with same function (assuming you believe js and ruby are equivalently concise for a similar application, which is a different debate).

In rails, you'd pull in a huge gem that does 50 things, many of which you don't use, but which may have security issues that effect you. You have less gems, but each one is much larger.

In node, you'd pull in small npm packages, that do single things. You have many more of them, but the total code size should be the same.

Arguably, its easier to review one large pile of code than many small piles of code. That can be argued, but I don't think you can claim that it is many factors easier.

Reviewing left-pad for security defects, for example, should be a matter of minutes.

All of which assumes that everybody reviews their dependencies for security defects, which isn't true for any language.

The many eyes make bugs shallow hypothesis is disproved every day for security.

Also, there is reference to social engineering. Again, compare many small packages with one or two developers, to a few large gems with many developers. Total developer count will probably be aproximately equal, so even the social engineering attack surface is similar.

npm can pull up its socks in some ways: signed package uploads, email notification of a publish to any owned repo (so we know if someone hijacked our repo or stole our credentials), and some other things, have all been excellent suggestions.

Everyone who has ever done `curl ...; tar -xf ..; ./configure` should be asking right now: how different is this?

A single Node of failure

Posted Apr 1, 2016 17:28 UTC (Fri) by bronson (subscriber, #4806) [Link] (2 responses)

It's not as similar as you imply. Those few Rails gems are used by tons of people and updated a few times per year, tops. Those many Node gems are in a constant state of churn.

> Reviewing left-pad for security defects, for example, should be a matter of minutes.

Multiply that by 400 dependencies, remember?

A single Node of failure

Posted Apr 1, 2016 21:32 UTC (Fri) by samroberts (subscriber, #46749) [Link] (1 responses)

rails line count of .rb files (excluding anything with test in the name or path): 111895 (1003 files)

express line count of lib/**/*.js: 3879 (11 files, I counted by hand)

And, yeah, your average express app uses a bunch of middleware... none of which will be as big and complex (<4000 lines) as express itself.

You can multiply by 400 all you want, and raise fear about OMG look how many modules node uses, its INSANE... but the fact remains, rails itself contains more code even before you add some gems than the 100s of package dependencies of many node projects.

Its just a different way of doing things. Node does a package per function or small set of functions, other languages have package systems that are so clunky and hard to use, they have to deliver code in large libraries, composed of dozens to 100s of files, and 100s to 1000s of APIs.

And sure, rails is used by a lot of people... but so is express and the set of packages around it, including, implicitly and recursively, all the dependencies.

A single Node of failure

Posted Apr 1, 2016 22:31 UTC (Fri) by bronson (subscriber, #4806) [Link]

I must be misunderstanding you... It sounds like you're talking about rails/rails? That's nine gems, plus database adapters, etc... How does it make any sense at all to compare it to the Express package?

Even if it did, I'm not sure how your comment applies to anything I said... Where am I talking about lines of code?

A single Node of failure

Posted Apr 2, 2016 0:37 UTC (Sat) by rgmoore (✭ supporter ✭, #75) [Link]

If you're worried mostly about errors that lead to security holes, your analysis may be correct. But in terms of malicious code, I'd take a large project over a host of small ones any day.

Somebody trying to slip malicious code into a big project has to get it by the other people working on the project, many of whom are likely to take a look at it before it gets into a shipping product. If they want to insert malicious code, they have to be clever enough to get it past the other developers on the project and, ideally, defend it as an innocent mistake if it's discovered.

In contrast, a tiny project with just one developer could put in malicious code with much less risk of detection. It would only get found if one of the projects that uses it decides to dig into the code and see what makes it tick, which is less likely because the whole point of including the code in the first place is to not have to think about what makes it work.

A single Node of failure

Posted Apr 7, 2016 7:42 UTC (Thu) by Wol (subscriber, #4433) [Link]

> The many eyes make bugs shallow hypothesis is disproved every day for security.

Like so many sayings, this one is misapplied every day, too ...

Read it carefully. It says "bugs are shallow". That means "IFF you're looking, they're easy to spot". It does NOT mean they will be stumbled across by chance. So no, it's not disproved. It's just totally irrelevant.

I'm sorry, but using sayings and claiming they mean something completely different does annoy me ... :-)

Cheers,
Wol

A single Node of failure

Posted Apr 1, 2016 15:17 UTC (Fri) by ksandstr (guest, #60862) [Link]

The problem is dependency confetti: instead of a small handful of dependencies (as in a relatively bloated desktop GTK+ application) a simple program can have that, and each of its direct dependencies will have another handful, etc., amounting to possibly hundreds of individually near-trivial packages where every one is able to break the build. As seen from the left-pad brouhaha, this tends to amplify various sources of instability -- in this case, corporate dick-swinging and (consequently) individual butthurt -- even if their effects weren't disproportionate in themselves.

It's secondary that each flake of confetti is at the level of "is this value an integer", or some other instance of "sprintf() is hard, let's restrict architecture to non-parameterized behaviour embodied as a billion little functions". Though that's a great example of programs being at least as dumb as their authors.

Since the node.js community sees micropackages as a good thing, the number of eventual dependencies per application-or-package will only get larger as the level of duplication increases. Because JavaScript is the idiot's language of 2016 (like PHP was in the nineties and aughties), duplication will increase with the number of JavaScript developers who find a comprehensive package too difficult to use compared to one that reimplements a subset of its functionality. Each micropackage has its developer, so it's turtles all the way down forevermore.

Really, the article is a little bit mistitled: there's not a single point of failure, but tens, hundreds, or thousands, depending on what's under the loupe and how "well-networked" it is.

A single Node of failure

Posted Apr 20, 2016 3:02 UTC (Wed) by zblaxell (subscriber, #26385) [Link]

There's a big difference between reusing code by reference and reusing code by value. ;)

A single Node of failure

Posted Mar 31, 2016 0:27 UTC (Thu) by bronson (subscriber, #4806) [Link] (1 responses)

NPM is easily the worst package manager I've ever used. Yearly kerfuffles, outages, lots of needless breakage (like 2014's cert debacle), massively redundant deps (44,000 files for hello world), etc...

I think most of NPM Inc's questionable decisions boil down to their being venture-backed and seeking revenue streams. Absolutely no way they'll open anything up to the community. The investors wouldn't allow it.

It's been difficult to watch. If the Node community is healthy, it will switch to an alternative package manager in the next few years. The pattern is clear, and the Node.js foundation could make it happen.

If it isn't healthy, then everyone will continue muddling along like this: at the whim of one company, developers always ready to whack things back together at a moment's notice. So be it.

A single Node of failure

Posted Mar 31, 2016 8:33 UTC (Thu) by bytelicker (guest, #92320) [Link]

I wholly agree. NPM is at times difficult to work with... and I do it daily to some extent. I have the feeling that it can break any moment. I've had it break multiple times which resulted in wasted time debugging. Sometimes the problems NPM can generate are not very apparent. Could be incomplete/broken sources, that aren't indicated or noticeable, breaking tests or the actual application.

A single Node of failure

Posted Mar 31, 2016 3:55 UTC (Thu) by gdietsche (guest, #74967) [Link] (1 responses)

The existence of that package is just an indication of how badly javascript and it's "standard" library is. The web constantly struggles and tries to work around problems in this language. That's why we have the new awesome framework of the week that does the same things differently in an attempt to make web development less painful. You can't fix fundamentally broken.

The web really needs a re-invention that makes apps first class citizens and implements something like web asm, or some other tech that allows developers to use the language of their choice. Larger projects need type safety, modulearity, etc. These are things that javascript just doesn't offer. Imagine how much smaller the modules from an interpreted language could be and how much faster the vm could execute the code. Today we waste tons of battery life because of the terrible state of the web.

Yes, I'm available for hire if you're working on a project to replace javascript with something more sane. Now if you'll excuse me, i need to get back to trying to properly center a div on 31337 different devices! Boss says it's off by 2 pixels on his windwos phone............

A single Node of failure

Posted Mar 31, 2016 5:17 UTC (Thu) by roc (subscriber, #30627) [Link]

A single Node of failure

Posted Mar 31, 2016 9:12 UTC (Thu) by ballombe (subscriber, #9523) [Link] (2 responses)

Why nobody has though about fixing line-numbers instead of reverting left-pad ?

A single Node of failure

Posted Mar 31, 2016 21:05 UTC (Thu) by bronson (subscriber, #4806) [Link] (1 responses)

A great question. I'm guessing it's because every reaction in this story, including NPM Inc's, was knee-jerk.

A single Node of failure

Posted Apr 1, 2016 21:28 UTC (Fri) by giraffedata (guest, #1954) [Link]

"I'm guessing it's because every reaction in this story, including NPM Inc's, was knee-jerk."

My guess is slightly different: people were shocked at how large an impact this small change caused - an impact that wasn't obvious before, so admitted things weren't as simple as they appeared and moved to immediately restore the status quo to give them room to take a breath and decide on the proper course of action.

Fixing line-numbers and deleting left-pad 0.0.3 is probably being considered.

A single Node of failure

Posted Mar 31, 2016 13:48 UTC (Thu) by Sesse (subscriber, #53779) [Link] (12 responses)

Mm, dependencies on a given, specific version because otherwise, everything could be changing below your feet at any given time. What do they do for version conflicts—pull in both?

C has a lot of faults, but at least it got ABI stability (through sonames) right in the end. It's sad that it's pretty much the only language that does.

A single Node of failure

Posted Mar 31, 2016 17:28 UTC (Thu) by MattJD (subscriber, #91390) [Link] (6 responses)

npm actually deals with this case better then C with sonames. In theory, every module get it's own execution environment and there is no shared global state between them. Instead a module will import a given module's state and make use of it. As long as no module tries to communicate with two different versions, it works out. Npm will even pull in multiple versions in some cases.

I don't believe every module actually get its own environment, it's just simulated. But it is done well enough in practise to not be a problem.

With C, if you pull in multiple different sonames into one executable, usually things break. No doubt this could be fixed, but now its a bad idea.

A single Node of failure

Posted Mar 31, 2016 17:45 UTC (Thu) by Sesse (subscriber, #53779) [Link] (5 responses)

No, that's not ABI stability. That's just locking down versions.

What you want is a system where you can make changes without dependent applications breaking. Having multiple versions installed is a nightmare when you have a security fix and need to make the same fix in 67 different places and versions.

A single Node of failure

Posted Mar 31, 2016 17:51 UTC (Thu) by MattJD (subscriber, #91390) [Link] (4 responses)

Yes, that does let you have multiple ABIs (the same thing sonames do).

I don't see how either version deals with security fixes across multiple ABIs. With sonames, I still need to upgrade each of the ABI versions, same as with npm. Assuming both use the proper versioning scheme (semantic versioning for node), I can upgrade all the packages to have that new version.

Now, wiht npm I may get stuck with a large dependency tree that I can't audit and may have a vulnerability I can't easily upgrade, no question. In theory if everyone maintains there package it works out. In practise, running `npm --depth 999 outdated` on my one project using node for preprocessing makes me want to never run node over untrusted data.

A single Node of failure

Posted Mar 31, 2016 19:38 UTC (Thu) by nybble41 (subscriber, #55106) [Link]

> Yes, that does let you have multiple ABIs (the same thing sonames do). ... I don't see how either version deals with security fixes across multiple ABIs. With sonames, I still need to upgrade each of the ABI versions, same as with npm.

Sonames don't address that problem, but symbol versioning does. That is how you can have a single version of libc that remains ABI-compatible with ancient applications and libraries, despite changes in the libc ABI over time. The backward-compatible symbol is generally a shim over the new ABI rather than a separate implementation, which helps keep the security fixes confined to one place. (Unfortunately, there aren't many other projects besides libc willing to expend the necessary effort to version their symbols.)

A single Node of failure

Posted Mar 31, 2016 19:45 UTC (Thu) by Sesse (subscriber, #53779) [Link] (2 responses)

The point isn't that it allows you to have multiple ABIs, it allows you to declare an ABI in the first place.

A single Node of failure

Posted Mar 31, 2016 19:58 UTC (Thu) by MattJD (subscriber, #91390) [Link] (1 responses)

Then npm has the same functionality through semantic versioning (Semver). The major number would then be similar to the soname, incremented when the ABI breaks. Semver only works when everyone follows it, and is in general a more loose policy then soname IMHO. But we have C libraries that don't follow the rules either, so it isn't universal.

Unless you mean Node developers have less standards then C developers on maintaining compatibility? That becomes a function on who the developer is. Anyone (C or Node) can accidentally (or on purpose) change their ABI and break downstream users (even the kernel will do that occasionally, they just have a very strict policy on what happens). Node developers may in general be worse (I don't have statistics, so I can't say either way), but npm does provide tools to deal with it. It isn't a tooling problem, but a people problem that affects all languages.

Anyways, I was originally responding to your comment about how they deal with differing module dependencies (that they do indeed pull in multiple version, and it can actually work in practise). And you can fix a security issue in multiple versions. Whether people actually do that is a whole other point.

A single Node of failure

Posted Mar 31, 2016 20:11 UTC (Thu) by Sesse (subscriber, #53779) [Link]

Sure, semantic versioning is a nice policy, but it's not “law” the same way C sonames are, and it needs to be pretty much universal for people to depend on it. (Also, infrastructure choices matter here; it _is_ technically possible for a C binary to depend on version 1.6.7 of a given library instead of ABI version 1, but you have to go out of your way to do it, so people don't.)

I'm sure there _are_ C libraries out there that don't care about sonames, but they're so rare I can't name a single one offhand. (And if you get it wrong out of ignorance, your Linux distribution maintainer will basically hit you with the cluebat and/or bump it for you whenever you break, plus usually take care of reverse dependencies so that the distribution as a whole only needs to carry one or at most a few versions of every module.)

And yes, it is my impression (although obviously somewhat subjective) that programmers of almost all newer languages are much worse than the average C programmer in maintaining backwards compatibility.

A single Node of failure

Posted Mar 31, 2016 19:25 UTC (Thu) by samroberts (subscriber, #46749) [Link] (3 responses)

Sounds like you have never used Node.js, because actually, since every module is required into the local scope of the requiring package, yes, you can have multiple versions of a package if necessary.

A single Node of failure

Posted Mar 31, 2016 19:44 UTC (Thu) by Sesse (subscriber, #53779) [Link] (2 responses)

I've used Node.js. And yes, I'm aware that this is what happens; I'm saying it's not a good solution to the problem of ABI stability. Read my previous reply.

A single Node of failure

Posted Mar 31, 2016 20:06 UTC (Thu) by samroberts (subscriber, #46749) [Link] (1 responses)

@sesse

you said

> What do they do for version conflicts—pull in both?

Answer: yes, both get pulled in, handily resolving conflicts.

A single Node of failure

Posted Mar 31, 2016 21:15 UTC (Thu) by bronson (subscriber, #4806) [Link]

You get a lot more than both. You get five versions of this lib, three versions that lib, a combinatorial explosion of packages. `ls -l node_modules | wc -l` is pure comedy in pretty much any nontrivial Node project.

For the sake of larger projects, NPM really should have implemented proper version resolution.

A single Node of failure

Posted Apr 11, 2016 15:20 UTC (Mon) by mstone_ (subscriber, #66309) [Link]

C may or may not have gotten it right, but essentially nobody uses sonames and versioned symbols properly/effectively so it mostly doesn't matter.

What are the licenses of the code provided?

Posted Mar 31, 2016 16:08 UTC (Thu) by southey (guest, #9466) [Link] (8 responses)

Surely we should not have to relearning the past when this type of thing happens. This keeps illustrating the importance of using code with appropriate licenses and why those licenses are so important!

What are the licenses of the code provided?

Posted Mar 31, 2016 19:18 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link] (7 responses)

What does a license have to do with this?? Anybody is entirely within their rights to stop distributing the code under any license.

What are the licenses of the code provided?

Posted Mar 31, 2016 20:10 UTC (Thu) by butlerm (subscriber, #13312) [Link] (6 responses)

The license makes all the difference in the world as to whether a third party has to stop distributing a previously released version of your code when you decide to.

Any operator of a public package management system is a de facto publisher. If they allow arbitrary contributors to un-publish their previously released contributions, they are promoting a unstable foundation that cannot be trusted to be used for anything.

What are the licenses of the code provided?

Posted Mar 31, 2016 20:38 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link] (5 responses)

> The license makes all the difference in the world as to whether a third party has to stop distributing a previously released version of your code when you decide to.
How? I fail to see a clause in the GPL saying: "NPM must always distribute the version 0.0.3 of left-pad library".

> Any operator of a public package management system is a de facto publisher. If they allow arbitrary contributors to un-publish their previously released contributions, they are promoting a unstable foundation that cannot be trusted to be used for anything.
That's true, but it had NOTHING to do with licenses.

It's entirely within NPM's legal rights to lock out the author and distribute the earliest possible version of left-pad with a couple of deliberate security vulnerabilities and a special 'crash often' mode.

What are the licenses of the code provided?

Posted Apr 1, 2016 12:09 UTC (Fri) by robbe (guest, #16131) [Link] (2 responses)

Nobody except you is talking about the GPL, though.

What are the licenses of the code provided?

Posted Apr 1, 2016 16:21 UTC (Fri) by drag (guest, #31333) [Link] (1 responses)

It's just a example. Cyberax jumped ahead in terms of logical consequences of the discussion.

A copyright owner isn't restricted by his own copyright. Thus any copyright license he has isn't going to restrict what he can do with his own code.

What is being argued here is that there exists a license which prevents a programmer from making his software unavailable from a hosting service.

It's silly.

One could argue that the hosting service itself is restricted by copyright so if some programmer puts his code on their servers then the hosting service is required by law to comply to the source code's copyright license. But I still think it's a frivolous line of reasoning that I doubt could hold much weight in court. The only person that can sue over copyright violations is the copyright holder. If the copyright holder wants to withdraw his code from a hosting service then it's going to be weird that he would turn around and sue them for doing exactly what he requested.

_maybe_ if it was a GPL license AND it was derivative of other people's work those other people could go to the hosting service and say that they must keep distributing it to comply with the terms of the GPL. But that's really pushing it.

All in all licensing has almost nothing to do with the issue at hand.

What are the licenses of the code provided?

Posted Apr 7, 2016 11:20 UTC (Thu) by oldtomas (guest, #72579) [Link]

It's just a example. Cyberax jumped ahead in terms of logical consequences of the discussion. A copyright owner isn't restricted by his own copyright. Thus any copyright license he has isn't going to restrict what he can do with his own code.
From the FL:
2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met.
This is for the GPL v3). See the "irrevocable" up there? The GPL v2 hasn't such a clarification as far as I can see, but still names no restrictions on your right to distribute code other than the well-known copyleft restrictions. This would cover Cyberax's example. I don't think other free (or any!) licenses allow revoking the rights granted unless explicitly stated. So no, the copyright holder can't (retroactively) take the right from you it has granted you in the first place. Now releasing new versions with a different license would be fair game, but this isn't what we are talking about here. Therefore I think that yes, an explicit license would help here.

What are the licenses of the code provided?

Posted Apr 4, 2016 5:39 UTC (Mon) by butlerm (subscriber, #13312) [Link] (1 responses)

> How? I fail to see a clause in the GPL saying: "NPM must always distribute the version 0.0.3 of left-pad library".

No. However, any open source license worth its salt gives NPM the _right_ to so, and given the business they are in, they need that right or their service is worthless.

What are the licenses of the code provided?

Posted Apr 4, 2016 7:07 UTC (Mon) by Cyberax (✭ supporter ✭, #52523) [Link]

Sure. But please, re-read the message I was answering to.

A single Node of failure

Posted Apr 1, 2016 12:12 UTC (Fri) by robbe (guest, #16131) [Link] (1 responses)

Even if NPM, Inc. is routed around in the future, the elephant in the room is: everybody and her brother is hosting their javascripts on GitHub, so this will be the send-to point for the next takedown notice.

A single Node of failure

Posted Apr 1, 2016 12:57 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

GitHub at least publishes all takedowns they receive.

A single Node of failure

Posted Apr 16, 2016 14:05 UTC (Sat) by diegor (subscriber, #1967) [Link]

I wonder what happens, if I trademark left-pad, and ask to remove left-pad module because violate my trademark.


Copyright © 2016, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds