The event-stream npm Supply Chain Attack

Updated 5 Oct 2026 · Incident date 9 Sept 2018 · npm

Packageevent-stream 3.3.5 -> 3.3.6 (payload in flatmap-stream 0.1.1, shipped 2018-10-05)
Fileflatmap-stream/index.min.js

event-stream 3.3.6 added a new dependency, flatmap-stream, and version 0.1.1 of that package carried hidden code. The code was built to steal bitcoin from users of the Copay wallet app.

Versions 3.3.4 and 3.3.5 of event-stream were clean. The attacker got publish rights by gaining the trust of the original maintainer.

What happened

A new contributor took over event-stream, added a malicious dependency, and waited about a month to arm it. Snyk's post-mortem gives this timeline.

Snyk reports that the attacker social-engineered the original maintainer, dominictarr, and received GitHub contributor access and full npm publishing rights.

The payload was in three stages. First, the code decrypted a hidden blob. It used the npm_package_description environment variable as the key. Because of this, the blob only decrypted when the host project had the description of the target app. Second, the payload ran only during build commands for iOS, Android or desktop. Third, it injected JavaScript into the @zxing/library dependency. That code collected data from wallets that held more than 100 BTC or 1000 BCH. The GitHub advisory says the module was written to target the Copay wallet app and sent the stolen data to an external server.

Developers found the problem in November 2018. A deprecation warning on 29 October 2018 started an investigation. On 19 and 20 November, the users NewEraCracker and FallingSnow flagged the code. The user maths22 then reverse-engineered it and found the decryption key by trying npm package descriptions. Read the Snyk post-mortem and the original GitHub issue.

This is a clear case of a new capability in a trusted package. A popular library gained a dependency that decrypted a blob, ran it, and wrote code into another package. A diff of the two releases shows that change. For similar cases, see all recorded attacks.

Affected versions

event-stream 4.0.0 removed the malicious dependency.

Indicators of compromise

The sources do not list file hashes or network addresses for this attack.

How to check

Search your dependency tree and lockfiles for flatmap-stream and for event-stream 3.3.6.

npm ls event-stream flatmap-stream
grep -rn "flatmap-stream" package-lock.json yarn.lock

Any result that shows flatmap-stream 0.1.1 means the package was installed. The code ran only in builds of the target app, so check the build history for Copay as well.

What to do now

  1. Remove flatmap-stream from the project and move event-stream to 4.0.0 or later, or remove it.
  2. Delete node_modules and the lockfile entries for flatmap-stream, then reinstall.
  3. If you build or use Copay 5.0.2 to 5.1.0, update to 5.2.0 and treat private keys as stolen, as Copay advised.
  4. Move funds to a new wallet with new keys if the old wallet used an affected version.
  5. Pin dependency versions and review the diff when a release adds a new dependency.

What Vigilance showed

Vigilance compares the version you trust with the new one and names the file that gained a new capability. The block below is rebuilt from the public reports in the words Vigilance prints. It is not a captured scan, because the malicious release is not redistributed.

vigi diff --old event-stream-3.3.5 --new event-stream-3.3.6
files scanned: 87 (1 Added)

HEADS UP  1 file can now do things the old version could not. The rest changed and gained nothing.

NEW FILE   flatmap-stream/index.min.js
           It reads saved passwords and access keys, runs other programs and runs a hidden, encoded command.

Frequently asked questions

Which event-stream version was malicious?

event-stream 3.3.6 added the flatmap-stream dependency. The injected code was in flatmap-stream 0.1.1. Versions 3.3.4 and 3.3.5 were clean.

What did the event-stream backdoor do?

It decrypted a hidden blob and ran it during builds of the Copay wallet app. It then injected code that collected private keys from wallets with more than 100 BTC or 1000 BCH.

How do I check if I installed flatmap-stream?

Run npm ls event-stream flatmap-stream and search your lockfiles for flatmap-stream. Version 0.1.1 is the bad one.

Sources

  1. github.com/advisories/GHSA-9x64-5r7x-2q53
  2. github.com/dominictarr/event-stream/issues/116
  3. snyk.io/blog/a-post-mortem-of-the-malicious-event-stream-backdoor/

More supply chain attacks

All 111 attacks in the library · npm supply chain attacks · How to prevent supply chain attacks

Check the next update before you install it

Vigilance compares the version you trust with the new one. It names the one file that can now do something it could not do before.

Start Free