[HN Gopher] Security issues related to the NPM registry
       ___________________________________________________________________
        
       Security issues related to the NPM registry
        
       Author : ManuelKiessling
       Score  : 260 points
       Date   : 2021-11-16 19:13 UTC (3 hours ago)
        
 (HTM) web link (github.blog)
 (TXT) w3m dump (github.blog)
        
       | yabones wrote:
       | Maybe it's just me, but the whole handling of this has been much
       | more Microsoft-ey than usual. Is this a sign the MS culture is
       | slowly seeping into GH?
        
         | rmbyrro wrote:
         | They didn't even have telemetry data before Microsoft and this
         | flaw has been sitting there probably since first day. If you
         | look closely, MS might be improving it, but I don't think MS
         | deserves credit nor blame here.
        
       | nfm wrote:
       | Because this is buried in the post and people don't seem to be
       | grokking it:
       | 
       | > Second, on November 2 we received a report to our security bug
       | bounty program of a vulnerability that would allow an attacker to
       | publish new versions of any npm package using an account without
       | proper authorization.
       | 
       | They correctly authenticated the attacker and checked they were
       | authorised to upload a new version of _their own_ package, but a
       | malicious payload allowed the attacker to then upload a new
       | version of a completely unrelated package that they weren 't
       | authorised for. Ouch!
        
         | jschrf wrote:
         | > However, the service that performs underlying updates to the
         | registry data determined which package to publish based on the
         | contents of the uploaded package file
         | 
         | Yeah, this is what's going to keep me up tonight. Yikes.
         | 
         | I can't help but wonder if the root cause was HTTP request
         | smuggling, or if changing package.json was enough.
         | 
         | How do we even mitigate against these types of supply-chain
         | attacks, aside from disabling run-scripts, using lockfiles and
         | carefully auditing the entire dependency tree on every module
         | update?
         | 
         | I'm seriously considering moving to a workflow of installing
         | dependencies in containers or VMs, auditing them there, and
         | then perhaps commiting known safe snapshots of node_modules
         | into my repos (YUCK). Horrible developer experience, but at
         | least it'll help me sleep at night.
        
           | staticassertion wrote:
           | A combination of things, I think.
           | 
           | 1. Running those builds in VMs is a good idea.
           | 
           | 2. Monitoring for weird behavior.
           | 
           | 3. Restricting build scripts from touching anything outside
           | of the build directory.
           | 
           | 4. Pressuring organizations like npm to step up their
           | security game.
           | 
           | It would be really nice if package repositories:
           | 
           | 1. Produced a signed audit log
           | 
           | 2. Supported signing keys for said audit log
           | 
           | 3. Supported strong 2FA methods
           | 
           | 4. Created tooling that didn't run build scripts with full
           | system access
           | 
           | etc etc etc
           | 
           | I started working on a crates.io mirror and a `cargo sandbox
           | [build|check|etc]` command that would allow crates to specify
           | a permissions manifest for their build scripts, store the
           | policy in a lockfile, and then warn you if a locked policy
           | increased in scope. I'm too busy to finish it but it isn't
           | very hard to do.
        
           | [deleted]
        
           | grey-area wrote:
           | _How do we even mitigate against these types of supply-chain
           | attacks_
           | 
           | Don't import thousands of modules from third parties just to
           | write a simple web app. If you have 10 stable dependencies
           | it's no problem to vendor them and vet changes. If you have
           | 10k you've entirely given up on any pretence of security.
        
           | 1propionyl wrote:
           | > I can't help but wonder if the root cause was HTTP request
           | smuggling, or if changing package.json was enough.
           | 
           | Maybe I'm just incredibly cynical from my experiences with
           | the intersection of the JS ecosystem and security, but...
           | 
           | ...I'd bet dimes to dollars it's the latter (just changing
           | the package.json). My guess is they authenticate but don't
           | actually scope the authentication properly, and no one
           | noticed because no one thought to look.
           | 
           | Of course, as we've seen in the past decade, there's so much
           | inertia behind the JavaScript ecosystem that none of this is
           | going to fundamentally change. It'll just take another decade
           | or so for the ecosystem to reinvent all of the wheels and
           | catch up to the rest of the space.
           | 
           | And at that point it will probably be considered stuffy and
           | "enterprise" and the new hotness unburdened from such
           | concerns will repeat the cycle again.
        
         | bigiain wrote:
         | That one, combined with the other "ability to read names of
         | private packages, makes for the possibility of a really really
         | sneaky attack. I wonder how many orgs treat their private npm
         | packages with significantly less scrutiny than the public ones
         | they rely on?
        
         | firebaze wrote:
         | No CVE mentioned. Hard to grok to me, could someone educate me
         | why this is missing in the blog post?
        
           | detaro wrote:
           | services don't get CVEs.
        
             | firebaze wrote:
             | Well, didn't we just experience two major npm published
             | packages containing malware? Both had CVEs.
             | 
             | Now we have the probable root cause, buried in a wall of
             | text. No CVE.
        
               | detaro wrote:
               | Yes, because pure services don't get CVEs. CVEs are for
               | distributed software.
        
               | firebaze wrote:
               | Isn't this _the_ biggest security flaw in the package
               | ecosystem ever?
               | 
               | They don't even know when, if, who and when this was
               | exploited, but maybe I didn't pay enough detail attention
               | to the few paragraphs devoted to the real problem.
               | 
               | So shoudn't we assume all NPM packages published prior to
               | 2nd of November are compromised?
               | 
               | And if so, shouldn't this deserve a CVE? (https://en.wiki
               | pedia.org/wiki/Common_Vulnerabilities_and_Exp...)
        
               | detaro wrote:
               | CVEs aren't usually assigned for "there might be
               | something wrong", but only identified specific issues.
        
               | cjbprime wrote:
               | CVEs alert end users that they need to take action to
               | apply updates. That's relevant when a specific npm
               | package contained a known vulnerability. It's not
               | relevant when the npm server contained a known
               | vulnerability. There's nothing a user of npm can do to
               | update the npm server.
               | 
               | CVEs don't just mean "this is a big security problem".
        
               | [deleted]
        
         | ptx wrote:
         | Also: "This vulnerability existed in the npm registry beyond
         | the timeframe for which we have telemetry to determine whether
         | it has ever been exploited maliciously."
        
       | [deleted]
        
       | tdiff wrote:
       | Ironically, lack of proper packet management in c++ saved c++
       | devs from the risk of being able to use random package with ease.
        
         | hmrr wrote:
         | Unfortunately that left them with the motivation to write their
         | own bus sized holes instead!
        
       | Amorymeltzer wrote:
       | Previous discussion (from less than 24 hours ago):
       | https://news.ycombinator.com/item?id=29234098
       | 
       | It came with the actual title, although arguably not the correct
       | one.
        
         | lucasyvas wrote:
         | Happy this got a second chance with a better title. I was in
         | the one yesterday and did a double take a few times when I was
         | reading it.
        
       | Mikeb85 wrote:
       | And people say Deno's model isn't secure SMH...
        
       | SavantIdiot wrote:
       | That second issue is the kind that scares me. Be it Rust, Python,
       | Node... public package managers have always seemed like a huge
       | risk to me with how we just assume nothing nefarious will be
       | installed b/c hey, npm repo said 11,000,000 downloads per week,
       | so it can't possibly be dangerous?
       | 
       | I'm guilty of this: my latest Nuxt project has 47,000
       | dependencies. yarn audit helps, but can i even trust that since
       | it is retroactive?
        
         | TillE wrote:
         | It's not really conceptually different from relying on third
         | party libraries in any context.
         | 
         | I haven't touched JavaScript since the late 90s, so I dunno
         | what the hell's going on there, but in my C++ projects I
         | typically have 10-20 dependencies (counting modularized Boost
         | as one). They're either built by a custom script which includes
         | the SHA256 of the tarballs it expects, or by a particular
         | pinned commit of vcpkg which likewise uses SHA512 to verify its
         | downloads.
         | 
         | I generally only update these when I need a new feature or bug
         | fix, which means I'm unlikely to get bitten by any temporary
         | security compromise.
         | 
         | If the "particular checkout of vcpkg" type of approach is
         | impossible with other package managers, that's unfortunate.
        
           | cnorthwood wrote:
           | Fortunately this is the default in JavaScript world with both
           | Yarn and NPM supporting lockfiles which have hashes and
           | pinned versions. The problem is the sheer volume of
           | dependencies and transient dependencies which makes it hard
           | to reliably audit those, as updating one thing can cause a
           | lot of work.
        
           | SavantIdiot wrote:
           | > I haven't touched JavaScript since the late 90s, so I dunno
           | what the hell's going on there,
           | 
           | Well you're in for a surprise: the entire web is built on
           | JavaScript for one thing. And that is build on frameworks
           | which are built on ... other frameworks, which are built on a
           | ginormous repository typically accessed by npm/yarn.
           | 
           | npm modules aren't the same as boost. Boost is written and
           | scrutinized by some of the best C++ minds on the planet.
           | 
           | npm modules are written by anyone. they are all open source,
           | but so many are in use that i doubt they get the scrutiny
           | they deserve. at one point there was a package just to left-
           | align things and a bug in it broke thousands of services.
           | 
           | but that's the landscape the modern web is built on, for
           | better or for worse.
        
         | ptx wrote:
         | Does that count duplicates, i.e. if a thousand different
         | packages depend on exactly the same version of some package X,
         | you get a thousand copies and count it a thousand times?
         | 
         | Otherwise I can't fathom how it's possible for a project to
         | have 47000 dependencies. I mean, my main Linux machine has all
         | kinds of old garbage installed and still the package manager
         | only lists 2000 packages.
        
           | SavantIdiot wrote:
           | Yes, it does include dupes, that's why I use yarn instead of
           | npm. That being said, sometimes it is multiple versions of
           | the same package, so yes-and-no.
        
       | raxxorrax wrote:
       | The headline doesn't really fit the issue.
       | 
       | content: The names of private packages were accidentally exposed
       | for a little over a week. The flaw has been found and fixed.
        
         | xPaw wrote:
         | There's more: > vulnerability that would allow an attacker to
         | publish new versions of any npm package using an account
         | without proper authorization.
         | 
         | > We determined that this vulnerability was due to inconsistent
         | authorization checks and validation of data across several
         | microservices that handle requests to the npm registry. In this
         | architecture, the authorization service was properly validating
         | user authorization to packages based on data passed in request
         | URL paths. However, the service that performs underlying
         | updates to the registry data determined which package to
         | publish based on the contents of the uploaded package file.
        
           | brazzledazzle wrote:
           | This seems like a much bigger deal. Disclosing private names
           | is not ideal but I think you have to assume your namespace
           | and package names will leak at some point. In my opinion you
           | should prepare for this well ahead of time by ensuring your
           | organization uses a unique namespace/org that matches your
           | internal/private namespace/org and squat on it. This will
           | prevent a supply chain attack where they take a leaked
           | namespace/package, register it and publish packages with
           | higher versions.
        
         | dang wrote:
         | Ok, we've replaced the title with the relevant subheading from
         | the article. Thanks!
         | 
         | The main article title is such corpspeak that it would go
         | against the site guidelines to use it--that sort of corporate
         | press release title is typically misleading, linkbait, or both.
         | 
         | https://hn.algolia.com/?dateRange=all&page=0&prefix=true&sor...
         | 
         | https://news.ycombinator.com/newsguidelines.html
        
           | ManuelKiessling wrote:
           | Call me old-fashioned, but I don't like the subheading.
           | 
           | This is not "security issues".
           | 
           | It was possible, for years, for anyone to upload anything for
           | any package.
           | 
           | For a package manager, this is THE security issue, all caps.
        
       | firebaze wrote:
       | This is probably the worst security problem ever in the JS
       | ecosystem. Any npm package could be corrupted, and we wouldn't
       | even know it if the original maintainers don't pay attention to
       | new releases anymore.
       | 
       | Still some people argue if this deserves its own CVE.
        
       | tdiff wrote:
       | Does the kind of flippant nature of packet management in js
       | ecosystem origins in the idea of js use cases being something
       | "not so important"? And when js expanded on backend the package
       | management approach was inherited?
        
       | xpressvideoz wrote:
       | > This briefly allowed consumers of replicate.npmjs.com to
       | potentially identify the names of private packages
       | 
       | When I was reading this, I thought the time frame would likely
       | have been on a time scale of hours (or even minutes),
       | 
       | > exposed between October 21 13:12:10Z UTC and October 29
       | 15:51:00Z UTC
       | 
       | But it's actually more than one week. Do we consider one week as
       | "brief"?
        
         | progbits wrote:
         | Right, and they don't even confirm who might have seen that
         | list, except that "the data on this service is consumed by
         | third-parties who may have replicated the data elsewhere". So
         | basically consider all private package names as of that date
         | forever public.
        
       | TedDoesntTalk wrote:
       | > we can say with high confidence that this vulnerability has not
       | been exploited maliciously during the timeframe for which we have
       | available telemetry, which goes back to September 2020.
       | 
       | Just over a year.
        
         | stingraycharles wrote:
         | Still is a good indicator, as you can assume that if some bug
         | was exploited a long time ago, it's very likely to continue to
         | be exploited in the present / until it is fixed.
        
       | SirensOfTitan wrote:
       | How is everyone dealing with this? I have no idea how to begin
       | auditing our dependencies for an issue like this.
       | 
       | GitHub really comes across looking like total garbage here with
       | this blog post. Security issues shouldn't be hidden like this.
       | This is dishonest and irresponsible.
        
         | Fordec wrote:
         | By getting off NPM entirely and new projects internally banned
         | from using it from day ome. Luckily all the backend stuff isn't
         | in javascript which is 80% of the battle.
        
           | hmrr wrote:
           | Genuine question as I quite frankly stay the hell away from
           | it: Can malicious NPM packages compromise your build
           | infrastructure?
        
       | austinkhale wrote:
       | Wow. Really bad news. Is there a way to automate looking at
       | packages published pre September 2020 and compare the contents to
       | publicly available repositories? It wouldn't cover all possible
       | malicious packages but it seems like it would be a start.
        
         | seniorsassycat wrote:
         | Package content can't be compared to a repository.
         | 
         | 1. npm doesn't record the repo, branch, or commit so it doesn't
         | know what to compare with.
         | 
         | 2. Published content is usually a transformation of the repo
         | content -compiled, minified, bundled. You would have to run the
         | same transformation on the repo source and it would have to be
         | a deterministic build.
         | 
         | npm could require that popular packages are published via
         | GitHub actions, then it could strongly associate the published
         | version with a source commit and the build that produced the
         | artifact.
         | 
         | This has some downsides like tie in to the GitHub ecosystem.
         | Maybe that could be offset with sponsored builds?
        
           | silverwind wrote:
           | For packages without a build, they could just do a checkout
           | on the repo and verify that the file hashes match the ones
           | about to be published.
           | 
           | Certainly not a complete solution but a good first step.
        
         | captn3m0 wrote:
         | Focusing on the most popular packages could make this feasible.
        
       | emeraldd wrote:
       | This feels like it should have wider ranging notice than it has
       | ...
        
       | thayne wrote:
       | > Transparency is key in maintaining the trust of our community.
       | 
       | and yet a security incident where it was possible to publish any
       | npm package without authentication is nine paragraphs down, and
       | isn't alluded to at all in the page or section titles. I'm not
       | sure that's entirely in the best spirit of transparency.
        
         | [deleted]
        
         | emteycz wrote:
         | Wasn't it fixed years ago?
        
           | agency wrote:
           | I believe it says the issue the OP is alluding to was
           | reported and fixed on Nov 2 - two weeks ago.
        
         | jabbany wrote:
         | At least the details were there. It's not the best organization
         | but they also didn't withhold anything.
        
           | croes wrote:
           | Hide it in the open isn't any better
        
       | andreisbc wrote:
       | This is dumb. Node and npm had years to solve this issue. Really
       | disrespectful towards the entire ecosystem. I get it: open
       | source, bla bla, but get your horses together and fix this
       | already
        
         | lucasmullens wrote:
         | > fix this already
         | 
         | They did.
        
           | rmbyrro wrote:
           | I don't think all consequences are fixed. At this point, no
           | one can assure the security of any npm package. What are they
           | doing to restore confidence?
        
           | jay_kyburz wrote:
           | No, the fix is a batteries included standard library for
           | JavaScript and the death of NPM.
           | 
           | I have high hopes for Deno.
        
       | julienb_sea wrote:
       | Amongst other things this is why enterprises that use Node
       | regularly have internal, private NPM registries with some delay
       | behind public releases.
        
         | TrueGeek wrote:
         | * should
        
         | deckard1 wrote:
         | This was common knowledge among Perl devs. Every place I've
         | worked that used CPAN did this. No one was pulling down random
         | versions of random packages off the interwebs like a lunatic. I
         | was amazed NPM didn't even have checksums a few short years
         | ago. Every security incident or fiasco (remember unpublished
         | packages??) I've simply nodded and said: yup. That was
         | obviously going to happen.
        
       | Rapzid wrote:
       | NPM keeps me up at night. We have a CRA with over 300k
       | node_modules files and over 1700 dependencies. Just one
       | compromised dep and suddenly someone else is driving your
       | AWS/Heroku CLI, stealing your credentials, and etc. There was
       | malicious dep version just a few weeks ago on an agent string
       | parser.
        
         | SavantIdiot wrote:
         | On top of that, have you had to go GitHub fishing to find a
         | fork of an abandoned package? Try chasing down a version of an
         | ffi module that doesn't keep ghosting.
        
         | ehutch79 wrote:
         | How many of those dependancies could be replaced with a single
         | line along the lines of if(number % 2 === 0){} ?
        
           | rectang wrote:
           | Even if you don't do that yourself, the culture is such that
           | lots of NPM authors would rather add a dependency -- thinking
           | nothing of the additional security risk due to package
           | takeover, nor the cost to downstream users who might actually
           | want to audit their dependencies.
           | 
           | The result is that instead of a dependency tree of consisting
           | of a few packages or a few dozen, you end up with an
           | unmanageable number like 1700 coming from who knows how many
           | authors.
        
             | mediumdeviation wrote:
             | I would not completely blame it on culture. There are
             | practical upsides to having a large number of packages -
             | using a dependency instead of duplicating code means the
             | resulting code is smaller, and splitting large packages up
             | allows you to only include specific functions you need.
             | This is important for the web, which is a lot more size
             | sensitive.
             | 
             | Nowadays tree shaking means that having a large package
             | with lots of smaller function should work better,
             | especially since adding an import incurs its own overhead,
             | but a lot of older packages are stuck on the small packages
             | model.
        
       ___________________________________________________________________
       (page generated 2021-11-16 23:00 UTC)