Incident analysis

Analysis: the event-stream npm attack

By Tolga SEZER - 2026-06-28

In short

In 2018, a popular npm package, event-stream, was handed to a new maintainer who added a malicious dependency (flatmap-stream) targeting a specific cryptocurrency wallet. It is a textbook maintainer-takeover plus poisoned-update attack, hidden in a transitive dependency.

What happened?

The original maintainer of event-stream, a widely-used package, handed control to a volunteer who offered to help. That new maintainer published a version adding a dependency, flatmap-stream, which contained obfuscated code targeting a specific wallet application to steal funds. Because event-stream was a dependency of many projects, the malicious code spread through transitive dependencies to projects that never installed it directly.

Why was it hard to spot?

The payload lived in a transitive dependency, not in event-stream itself, and it was obfuscated and narrowly targeted, so it stayed quiet for most users. Reading event-stream alone would not reveal it; the risk was one level down and only in a specific version.

How would automated analysis have helped?

Diffing the version that added the new dependency, plus running it through deobfuscation and a sandbox, would have surfaced the obfuscated, wallet-targeting behavior and the newly introduced dependency as a high-risk delta - the kind of change that should block adoption pending review.

FAQ

Common questions

What is a transitive dependency attack?
Malicious code placed in a package you depend on indirectly, so it reaches your project through your dependencies' dependencies rather than anything you installed directly.
How do you defend against maintainer takeover?
Re-analyze new versions after an ownership or maintainer change, diff what each release adds, and inspect newly introduced dependencies before adopting them.