You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Gathering-weak-npm-credentials.md
+18-18Lines changed: 18 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,9 @@
1
1
# Gathering weak npm credentials
2
2
3
3
_Or how I obtained direct publish access to 14% of npm packages (including popular ones)._\
4
-
_The estimated number of packages potentially reachable through dependency chains is 53%._
4
+
_The estimated number of packages potentially reachable through dependency chains is 54%._
5
5
6
-
_Numbers updated on 2017-07-05 — minor changes._
6
+
_Numbers updated on 2017-07-15 — small update._
7
7
8
8
---
9
9
@@ -43,28 +43,28 @@ The main task of this post is to show the dangers of using weak/reused/leaked pa
43
43
44
44
## Results
45
45
46
-
In total, there were 72298 public packages from 16735 accounts directly affected — about 14% of the whole npm ecosystem.
46
+
In total, there were 73983 public packages from 17088 accounts directly affected — about 14% of the whole npm ecosystem.
47
47
48
-
Taking dependencies into an account, to my estimations about 53% of the ecosystem was affected — i.e. that number of packages install affected ones along with them through dependency chains.
48
+
Taking dependencies into an account, to my estimations about 54% of the ecosystem was affected — i.e. that number of packages install affected ones along with them through dependency chains.
49
49
50
50
_That said, dependency chains and semver are not the culprits — grouping deps into larger modules wouldn't have fixed anything and breaking semver would have caused more security problems.
51
51
I will (hopefully) cover that later, but [@joepie91](https://github.com/joepie91) has some notes about that in [his gist](https://gist.github.com/joepie91/828532657d23d512d76c1e68b101f436)._
52
52
53
53
### Overall
54
-
* In total, I found **16836 valid credentials for 16735 accounts** since this May.
55
-
* Of those, 16550 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 **13% of accounts with leaked or weak credentials**.
56
-
* The total number of directly affected packages was **72298 — 14% of the ecosystem**.
57
-
* The total percentage of indirectly affected packages is estimated to be about **53% of the ecosystem** — that is, including packages affected by dependencies.
54
+
* In total, I found **17192 valid credentials for 17088 accounts** since this May.
55
+
* Of those, 16901 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 **13% of accounts with leaked or weak credentials**.
56
+
* The total number of directly affected packages was **73983 — 14% of the ecosystem**.
57
+
* The total percentage of indirectly affected packages is estimated to be about **54% of the ecosystem** — that is, including packages affected by dependencies.
58
58
* I obtained accounts of **4 users from the top-20 list**.
59
-
* Of the affected accounts, **41 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**.
59
+
* Of the affected accounts, **42 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**.
60
60
* One of the passwords with access to publish [koa](https://www.npmjs.com/package/koa)**was literally «`password`»**.
61
61
* 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.
62
62
* 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).
63
63
* 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](https://medium.com/@malcomvetter/offensive-passwords-451371ccd02e) — those could (and in this case were) leaked to the public in cleartext.
***1409 users (1%) used their username as their password**, in its original form, without any modifications.
66
-
***11% of users reused their leaked passwords**: 10.4% — directly, and 0.6% — with very minor modifications.
67
-
* Total downloads/month of the unique packages which I got myself publish access to was 1 962 815 947, that's **20% of the total number of d/m** directly.
66
+
***11% of users reused their leaked passwords**: 10.6% — directly, and 0.7%— with very minor modifications.
67
+
* Total downloads/month of the unique packages which I got myself publish access to was 1 972 421 945, that's **20% of the total number of d/m** directly.
68
68
69
69
### Packages
70
70
@@ -164,19 +164,19 @@ Overall, 46 packages have more than 10 million downloads/month (of those, 22 are
164
164
165
165
_Note that some of those packages have had the number of owners reduced since then, so attempting to guess the affected users by that is likely to give wrong results. I specifically excluded packages owned by single users from the list — there were significant ones. Also, npm registry and website both sometimes return the owners list incorrectly, and that is the case for at least some of the above-mentioned packages._
166
166
167
-
I got publish access to [component-emitter](https://www.npmjs.com/package/component-emitter) (and a lot more related) via 10 independent users, to [domify](https://www.npmjs.com/package/domify) — via 9 users, [array-parallel](https://www.npmjs.com/package/array-parallel) and a lot of [mongodb-js](https://github.com/mongodb-js) components — via 5 users each, [superagent](https://www.npmjs.com/package/superagent) — via 3 users, [cheerio](https://www.npmjs.com/package/cheerio), [browserify](https://www.npmjs.com/package/browserify), [koa](https://www.npmjs.com/package/koa), [mongoose](https://www.npmjs.com/package/mongoose), [modernizr](https://www.npmjs.com/package/modernizr), [react](https://www.npmjs.com/package/react), [tape](https://www.npmjs.com/package/tape), [winston](https://www.npmjs.com/package/winston), [ws](https://www.npmjs.com/package/ws) — via 2 users each. I'm also not listing all of those, 2237 packages in total were accessible through more than one user, 40 of those with more than 1 millon downloads/month, 7 — with more than 10 million downloads/month.
167
+
I got publish access to [component-emitter](https://www.npmjs.com/package/component-emitter) (and a lot more related) via 10 independent users, to [domify](https://www.npmjs.com/package/domify) — via 9 users, [array-parallel](https://www.npmjs.com/package/array-parallel) and a lot of [mongodb-js](https://github.com/mongodb-js) components — via 5 users each, [superagent](https://www.npmjs.com/package/superagent) — via 3 users, [cheerio](https://www.npmjs.com/package/cheerio), [browserify](https://www.npmjs.com/package/browserify), [koa](https://www.npmjs.com/package/koa), [mongoose](https://www.npmjs.com/package/mongoose), [modernizr](https://www.npmjs.com/package/modernizr), [react](https://www.npmjs.com/package/react), [tape](https://www.npmjs.com/package/tape), [winston](https://www.npmjs.com/package/winston), [ws](https://www.npmjs.com/package/ws) — via 2 users each. I'm also not listing all of those, 2367 packages in total were accessible through more than one user, 41 of those with more than 1 millon downloads/month, 8 — with more than 10 million downloads/month.
168
168
169
169
### Detailed
170
170
* Bruteforce attack using very weak passwords gave me 5994 total packages from 2803 accounts.
171
-
*[Utilizing](https://twitter.com/slatestarcodex/status/854382497261596676) datasets from known public leaks gave me 60089 total packages from 13013 accounts (directly).
172
-
* Fuzzing the passwords from those known public leaks a bit (appending numbers, replacing other company names with «`npm`», etc) gave me 6772 packages from 852 accounts.
173
-
* New npm credentials leaks (GitHub, Google, etc) gave me 586 total packages from 126 accounts.
171
+
*[Utilizing](https://twitter.com/slatestarcodex/status/854382497261596676) datasets from known public leaks gave me 61536 total packages from 13358 accounts (directly).
172
+
* Fuzzing the passwords from those known public leaks a bit (appending numbers, replacing other company names with «`npm`», etc) gave me 7064 packages from 856 accounts.
173
+
* New npm credentials leaks (GitHub, Google, etc) gave me 645 total packages from 136 accounts.
174
174
175
175
#### Leaks of npm credentials on GitHub and other places
176
176
177
177
These are some of the packages that I got myself publish access to by collecting npm credentials leaked to various places recently: [conventional-changelog](https://www.npmjs.com/package/conventional-changelog), [fetch-mock](https://www.npmjs.com/package/fetch-mock), [sweetalert2](https://www.npmjs.com/package/sweetalert2).
178
178
179
-
In total, there were 131 accounts and 623 packages.
179
+
In total, there were 136 accounts and 645 packages, totaling to 785 859 downloads/month.
180
180
181
181
This is mostly covered in the [previous post](Do-not-underestimate-credentials-leaks.md) — I made a tool to automatically gather those using the GitHub API, and validate gathered results on npm `/whoami`. I shared that tool with npm, Inc.
182
182
@@ -200,7 +200,7 @@ The bruteforcer activity was noticed and prevented (via an IP ban) after approx
200
200
201
201
#### Reused passwords leaked from other services
202
202
203
-
This gave me 60089 total packages from 13013 accounts directly, totaling to 1 707 014 153 downloads/month.
203
+
This gave me 61536 total packages from 13358 accounts directly, totaling to 1 716 708 126 downloads/month.
204
204
205
205
As that is the most part of the data — I will not repeat the affected packages list.
206
206
@@ -214,7 +214,7 @@ By «fuzzing» I mean performing modifications to passwords gained from third-pa
214
214
215
215
Fuzzing included (among other attempted modifications): changing the capitalization, appending/removing digits (and other symbols) at the end, replacing company names with `npm`, appending/prepending `@npm` (and others), and other various changes. That was quickly achievable because there were already known potential passwords matched for each account — and there were not too many of those, so even multiplying those by one or two orders of magnitude (depending on the account significance) was possible.
216
216
217
-
That gave me 6772 packages from 852 accounts. The top package gained that way had 10 millon downloads/month, and the total was 171 940 255 d/m.
217
+
That gave me 7064 packages from 856 accounts. The top package gained that way had 10 millon downloads/month, and the total was 172 436 393 d/m.
218
218
219
219
[react](https://www.npmjs.com/package/react), [redux](https://www.npmjs.com/package/redux), [browserify](https://www.npmjs.com/package/browserify), [rollup](https://www.npmjs.com/package/rollup), [sinon](https://www.npmjs.com/package/sinon), and other packages were directly affected.
0 commit comments