npm

Tens of thousands of developers using weak credentials to secure their npm accounts inadvertently put more than half of the npm packages (JavaScript libraries and tools) at risk of getting hijacked and used to deploy malicious code to legitimate applications that use them in their build process.

npm Inc, the company that runs the npm package manager, has addressed the issue at the start of June by triggering password reset operations for all affected users.

Initially, there was a lot of confusion about npm Inc's actions, and many believed the organization might have been breached. It was only over the last weekend when we discovered the real reason behind the massive npm account password resets that took place at the start of the month.

Node.js project member at the heart of it all

Behind it all was Nikita Andreevich Skovoroda, a Moscow-based developer and member of the Node.js CTC (Core Technical Committee).

Speaking to Bleeping Computer, the developer said he performed a series of checks for leaked passwords since May this year, and forwarded the results to npm Inc, who then opted to reset the passwords of all affected users.

Skovoroda's interest in exposing leaked passwords didn't come out of the blue. The developer has been warning npm users since 2015 when he first started noticing careless developers leaving passwords for their npm accounts in their code or other places.

"I was originally working on some other thing: a crude code scanner over all of npm packages to check how frequent and where are some Node.js APIs being used, for the needs of [Node.js] project," Skovoroda told Bleeping Computer in a private conversation about his initial 2015 scan.

"Back then, I noticed packaged credentials in some npm packages," he added. "That was [an] issue I reported to npm Inc over email back then."

The result of his initial report was that npm Inc added a feature to scan for user credentials in npm packages and revoke them.

Researcher finds npm accounts secured with weak credentials

"This [latest] check was started at the beginning of May on the Node.js collaborator summit [...] mostly in free time, with a tool to collect the published credentials from GitHub and check them against npm automatically," Skovoroda says.

The developer later improved his scanner to check if npm accounts used common passwords such as "123456," "password," or others; and later to check for cleartext passwords leaked in public breaches such as the ones from Adobe, Last.fm, and others.

"I was mostly doing this at a slow pace in my free time until the scan over leaked passwords started giving me lots of valid accounts," Skovoroda says, "I didn't expect that to happen originally."

When he finished, the developer says he forwarded the results of his scan to npm's team, who reset passwords for all affected accounts.

Scan results were bad. Really bad.

If a malicious actor would have scanned and discovered these issues before Skovoroda, the attacker could have gained direct "publish access" to 66,876 npm packages, representing nearly 13% of the entire JavaScript npm ecosystem.

This is a huge issues because gone are the days when developers load JavaScript libraries by hand in their code. Nowadays, developers primarily use npm to load the libraries they need using npm's dependency management system.

This automatic dependency management system means that when a developer loads npm package A, he also loads its dependencies, npm packages B, C, D, E, F, G, etc..

While Skovoroda discovered credentials that granted him direct publish access to only 13% of npm packages, through dependencies, an attacker would have been able to spread his malicious code to about 52% of the entire npm ecosystem.

Whenever the owner of an indirectly affected package rebuilt his project — for an update or bugfix release — he would have loaded the tainted npm packages into his project, and granted the attacker a means to reach his users.

Thanks to Skovoroda's forward thinking, npm Inc was alerted and has now implemented extra checks that will automatically ask users to change their passwords if they use simplistic or previously exposed credentials.

15,495 npm accounts found using weak passwords

Below are some of the other results of Skovoroda's scan, some of which readers will find very interesting.

  • In total, I found 15568 valid credentials for 15495 accounts since this May.
  • Of those, 15343 accounts have published something (I was targeting only those for everything but npm credentials leaks). The total number of such accounts on npm was 125665, so that gives us 12% of accounts with leaked or weak credentials.
  • The total number of directly affected packages was 66876 — 13% of the ecosystem.
  • The total percentage of indirectly affected packages is estimated to be about 52% of the ecosystem — that is, including packages affected by dependencies.
  • I obtained accounts of 4 users from the top-20 list.
  • Of the affected accounts, 40 users had more than 10 million downloads/month (each). For comparison, express package has 13 million downloads/month atm. 13 users had more than 50 million downloads/month.
  • One of the passwords with access to publish koa was literally «password».
  • One of the users directly controlling more than 20 million downloads/month chose to improve their previously revoked leaked password by adding a ! to it at the end.
  • One of those 4 users from the top-20 list set their password back to the leaked one shortly after it was reset (so it got reset again).
  • At least one password was significantly inappropriate — to the extent that one wouldn't want that to be linked to them online and could be publicly blamed in that case (i.e. not just a swearword). Don't use offensive passwords — those could (and in this case were) leaked to the public in cleartext.
  • 662 users had password «123456», 168 — «123», 115 — «password».
  • 1409 users (1%) used their username as their password, in its original form, without any modifications.
  • 10% of users reused their leaked passwords: 9.7% — directly, and 0.6% — with very minor modifications.
  • Total downloads/month of the unique packages which I got myself publish access to was 1 946 302 172, that's 20% of the total number of d/m directly.

The frailty of the npm JavaScript ecosystem has been discussed before, last year, when an angry developer pulled his project offline and indirectly brought down thousands of other JS tools that had included his package in their dependencies.

Similarly, a team of researchers detailed the possibility of an npm worm that would also use npm dependencies to spread and infect other npm packages.
 
Image credits: npm, Inc., Bleeping Computer