Safeguard
Incident Analysis•

event-stream npm: what happened and what defenders should learn

In 2018 malicious flatmap-stream rode into event-stream after a maintainer handoff. A short timeline and four controls that would have helped defenders.

Safeguard Security Team
4 min read

In November 2018, a developer found encrypted malicious code in flatmap-stream 0.1.1, a dependency added to the popular npm package event-stream 3.3.6 after its maintainer handed the project to a newcomer. The lesson for defenders is that trust in a package name does not carry over when ownership changes.

The facts below come from the public GitHub issue thread where the discovery was reported. Details of the payload come from community analysis in that thread, so treat them as reported, not as confirmed findings.

What is the timeline?

  • 20 November 2018: A user opens issue 116 on the event-stream repository, titled "I don't know what to say.", reporting malicious code in flatmap-stream 0.1.1. The package was a dependency of event-stream 3.3.6, which many other packages pulled in, including ps-tree, npm-run-all and nodemon.
  • 22 November 2018: The original maintainer says he had handed maintenance to a user who asked to take over. He says he no longer used the module and no longer had publish rights.
  • 26 November 2018: The thread notes that fixes had been deployed and that npm had yanked the malicious version.
  • 28 November 2018: The repository was archived by its owner.

What did the code do?

The payload was AES-encrypted and hidden in a minified file. The first analysts could not fully decrypt it. Later comments in the thread describe a payload that only ran when a specific package description matched, used as the decryption key, and a variant that reportedly aimed at a bitcoin wallet application and sent data to remote hosts on port 8080. The thread labels these as community findings.

For defenders the interesting part is the design: code that stays inert unless it runs inside a particular target is hard to find by running it in a generic sandbox.

Why did it spread?

Nobody had to install flatmap-stream on purpose. It came in as a dependency of a dependency. Most projects that were exposed had never typed the name.

The ownership handoff is the second factor. The maintainer says he handed the project to a person who asked to take over, and critics in the thread argued about responsibility. The more useful reading for a defender is structural: open source maintenance often sits with one tired person, and an offer of help is a normal event that looks the same as an attack.

What should defenders do differently?

Know your transitive tree. The thread's own advice was to run npm ls event-stream flatmap-stream to check exposure. That only works if someone thinks to ask. Keep an inventory per build so the question takes a minute.

Watch for new dependencies in updates. The malicious code arrived through a new dependency, flatmap-stream. Flag any update that adds a package you have not used before.

Pin and review. The thread's fix advice was to pin event-stream to 3.3.4. A lockfile with reviewed updates gives you that by default.

Check for ownership change. A new publisher on a heavily used package deserves a look before you adopt the next release.

What to do

  1. Generate a dependency inventory with versions for each build, including transitive packages.
  2. Use lockfiles and update on purpose, not automatically.
  3. Alert when an update adds a new transitive dependency.
  4. Alert when a package you depend on changes publisher.
  5. Run builds in an environment without production secrets.
  6. Practice the response: find every build that contained a package, then rebuild.

Quick check

Was event-stream itself hacked?

According to the issue thread, the maintainer had handed the project to a user who asked to take over. The malicious code was added through a new dependency, flatmap-stream.

How would you check exposure today?

List your resolved dependency tree, for example with npm ls for the two package names, and search your build inventory for affected versions.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.