Case Study

How nproxy can flag event-stream attack signals

In November 2018, a malicious payload was discovered inside event-stream, an npm package with roughly 2 million weekly downloads at the time. The attack targeted Bitcoin wallets and went undetected for over two months. Three nproxy security rules can flag it at install time.

Published April 1, 2026

What happened

event-stream was a popular utility for working with Node.js streams, originally maintained by Dominic Tarr. In September 2018, a user named right9ctrl offered to take over maintenance. Tarr, who had moved on from the project, transferred publish access.

right9ctrl published event-stream@3.3.6, which added a new dependency: flatmap-stream. This package was brand new on npm, published solely for this attack. It contained an encrypted payload that was designed to activate only when running inside the Copay Bitcoin wallet application.

The payload stole wallet credentials and private keys, sending them to an attacker-controlled server. It went undetected from September to November 2018 because the malicious code was encrypted and only decrypted at runtime under specific conditions.

Timeline
  • September 2018 — right9ctrl gains publish access to event-stream
  • September 9, 2018 — event-stream@3.3.6 published with flatmap-stream dependency
  • October 5, 2018 — flatmap-stream@0.1.1 published with encrypted malicious payload
  • November 20, 2018 — Community member reports the issue on GitHub
  • November 26, 2018 — npm unpublishes flatmap-stream

Which nproxy rules can flag this pattern

nproxy evaluates package requests at fetch/install time and can block or warn before dependency resolution completes. Three of the six default security rules are directly relevant to the event-stream attack pattern.

publisher_change
warn

Warns when a package version is published by a different maintainer than previous versions. event-stream had been published exclusively by Dominic Tarr for years. When right9ctrl published 3.3.6, the publisher identity changed. nproxy can flag this transition and surface a warning at install time.

first_seen
block

Can block versions published within the last 7 days, giving the ecosystem time to vet new releases. flatmap-stream was a brand-new package created specifically for this attack. It had zero history, zero community vetting, and zero prior versions. Any organization with the first_seen rule enabled can block flatmap-stream during its initial quarantine window.

unexpected_deps
warn

Warns when a new version adds dependencies that were never part of the package before. event-stream@3.3.4 (the prior version) had a stable dependency tree. Version 3.3.6 suddenly introduced flatmap-stream as a new dependency. nproxy can flag this as an unexpected dependency change, giving teams a signal to investigate before installing.

Any one of these rules can surface a warning or block. Together, they create overlapping coverage for exactly this class of supply chain attack: a trusted package changing hands and introducing a malicious dependency.

Note: nproxy does not guarantee that all supply chain attacks will be caught. These rules are designed to flag common risk patterns and give teams time to investigate.

What developers can see

With nproxy configured, a developer running npm install on a project depending on event-stream can see policy enforcement happen transparently in the install path. No extra tools, no context switching.

Terminal

$ npm install event-stream

resolving packages via acme.nproxy.app...

WARN event-stream@3.3.6 — publisher_change: published by right9ctrl (previous: dominictarr)

WARN event-stream@3.3.6 — unexpected_deps: new dependency flatmap-stream not in prior versions

BLOCKED flatmap-stream@0.1.1 — first_seen: published 2 days ago (threshold: 7 days)

resolution failed — blocked dependency in tree

$

How nproxy works

nproxy is a transparent package registry proxy. You point your package manager at your nproxy endpoint and every package request is evaluated against your configured security rules before the package reaches your machine.

Setup takes one line in your .npmrc. Developers keep using npm install, pnpm install, or yarn as usual. There is no CLI to install, no browser extension, no CI plugin required.

npm / pnpm (.npmrc)
registry=https://acme.nproxy.app/
yarn (.yarnrc.yml)
npmRegistryServer: "https://acme.nproxy.app/"
GitHub Actions
- uses: actions/setup-node@v4
  with:
    node-version: 20
    registry-url: "https://acme.nproxy.app/"

Replace acme with your organization's subdomain. You receive your subdomain when you create a free account at nproxy.app.

Why install-path enforcement matters

The event-stream attack was not detected by npm audit, by GitHub security advisories, or by any CI-based scanner at the time. It was found by a developer who noticed unusual code in a dependency and opened a GitHub issue.

Scanners that run after install, in CI, or on pull requests operate on code that has already been downloaded and potentially executed. Install scripts run during npm install — before any scanner has a chance to flag anything.

Install-path enforcement evaluates packages before they reach the developer's machine. The policy decision happens at the proxy layer, where the package can be blocked or warned about before any code executes locally.

This pattern keeps repeating

The event-stream attack was not an isolated incident. The same pattern — a trusted package changing hands, introducing a new dependency, or being published by a new maintainer — has appeared repeatedly in the npm ecosystem:

  • ua-parser-js (2021) — Maintainer account compromised. Malicious versions published with cryptominer and credential stealer. ~24M weekly downloads at the time.
  • coa and rc (2021) — Maintainer accounts hijacked. Malicious versions published to widely-used packages in the React ecosystem.
  • colors and faker (2022) — Original maintainer published corrupted versions as protest. publisher_change does not catch this case (same publisher), but the incident highlights why defense in depth matters.

In each case where a new publisher was involved, the publisher_change rule can surface a warning. In cases involving new dependencies, unexpected_deps can flag the change. These are not hypothetical — they are the exact patterns these rules are built to detect.

Sources

Stop risky packages before they reach production

One command, every install enforced against your policy. CI and production deploys gated on Team plans. Your team keeps using npm as usual.