Echo — event-stream (2018)
What happened
event-stream was a small, extremely popular utility for working with streams in Node.js — the kind of dependency that thousands of projects pull in transitively and nobody thinks about. Its original author had long since stopped using it, so when a stranger volunteered by email to take over maintenance, the author granted that person publishing rights to the package. Months later, in late 2018, the new maintainer added a new dependency, flatmap-stream, that carried obfuscated malicious code. The compromise was found not by any downstream victim's tooling but by a community member who noticed the odd new dependency and opened GitHub issue #147 on the event-stream repository.
The mechanism
The root cause was a trust handoff at the top of the dependency graph, adopted automatically at the bottom. The original maintainer, no longer invested, handed publishing rights to someone he did not know — and npm's model gave that new account the power to ship code into every downstream build that resolved the package. The payload was deliberately quiet: rather than misbehaving everywhere and getting caught, it stayed dormant except inside the build of one specific target — the Copay bitcoin wallet — where it decrypted itself using the target package's own description as the key and attempted to steal wallet secrets. A minor-version bump of a transitive dependency is exactly the change no reviewer ever opens, which is why it survived long enough to reach production for the ecosystem at large.
flowchart TD
A["Original author stops using event-stream"] --> B["Hands publishing rights to a volunteer"]
B --> C["Volunteer adds a new dependency, flatmap-stream"]
C --> D["Obfuscated payload hidden inside it"]
D --> E["Fires only inside the Copay wallet build"]
E --> F["Community finds it in issue 147"]
Blast radius
event-stream was downloaded on the order of millions of times a week (reported around two million), so one poisoned release rode that reach into a very large number of downstream builds. The payload itself was surgically narrow — it only activated against the Copay wallet — so most projects that pulled the bad version were never directly harmed. But the discovery still triggered an ecosystem-wide "are we exposed?" scramble, and most teams could not answer quickly: nobody had recorded which of their build artifacts actually bundled which version of which transitive package. The alarm arrived from strangers on the internet; the inventory, for most, had to be reconstructed by hand.
The same-class lesson
A dependency is a stranger with commit access to your production builds. The transferable reflex is threefold, and it is exactly the shape of Drill 60. Pin every version in a lockfile so nothing reaches production without a reviewed commit. Put a cooling-off window between a release being published and your systems adopting it, so the ecosystem gets to be your canary before the code touches your builds. And keep an SBOM (Software Bill of Materials — a machine-readable inventory of every component in a build) so that "are we exposed?" is a query answered in minutes, not an archaeology dig measured in days. Currency is a real security virtue against known vulnerabilities — but unattended, immediate adoption of fresh releases trades it for zero-day supply-chain exposure. Update on purpose, on a cadence, behind a pin.
Rhymes with
Drill 60 — The Package That Turned.
Named concepts: supply-chain security, dependency pinning, SBOM, cooling-off windows.
