Incident ResponseApril 4, 2026 · 8 min read

We Ran Koalr Against the Commit That Compromised 8 Million npm Downloads. It Scored 94.

In 2018, a GitHub user with no prior history asked to help maintain event-stream — one of the most downloaded npm packages in the world. The original maintainer said yes. Eight million downloads later, a backdoor had been silently stealing Bitcoin wallets. We ran our 36 risk signals against the exact commit. Every major signal fired.

94

Retroactive risk score: 94 / 100

This is a retroactive analysis. Koalr did not exist in 2018. The signals below are derived from publicly available commit history, npm audit logs, and post-mortem documentation. We are applying our current scoring model to historical data to illustrate what pre-merge risk detection would have surfaced.

What happened

In September 2018, a GitHub user named right9ctrl opened an issue on dominictarr/event-stream asking to help maintain the project. Dominic Tarr, the original author, had moved on to other work. He accepted the offer and handed over npm publishing rights.

What followed was a textbook supply chain attack. right9ctrl added a new dependency — flatmap-stream — published from their own account. That package contained obfuscated code that, when combined with a specific target application (the Copay Bitcoin wallet), decrypted and executed a payload designed to steal private keys.

The attack went undetected for over two months. By the time it was discovered on November 20th, the malicious version had been downloaded approximately 8 million times.

The signals that fired

Koalr evaluates 36 signals across five categories: contributor history, change characteristics, dependency risk, code ownership, and deployment timing. Here is what the event-stream commit triggered:

SignalCategoryScore impact
New contributor with zero commit history given ownershipContributor history+35
External dependency introduced by first-time contributorDependency risk+22
No CODEOWNERS review from original maintainerCode ownership+18
Original maintainer inactive for 180+ daysContributor history+12
No test coverage added for new dependencyChange characteristics+7
Total risk score94

The highest-weighted signal: contributor history

The single biggest risk factor was not the malicious dependency. It was the contributor.

right9ctrlhad no public commit history on GitHub at the time of the handover. A contributor with zero prior commits to any repository was given full npm publishing rights and merge access to a package with 11 million weekly downloads. In Koalr's model, author experience is one of the most predictive signals for deployment risk. Academic research on software defect prediction consistently shows that changes from contributors with less than 90 days of project history have a significantly higher defect rate.

A new contributor taking over maintenance of a high-impact package is not inherently malicious. But it is a risk event that should have triggered a review conversation — and it did not.

The dependency nobody looked at

flatmap-stream was published by right9ctrl from their own npm account and added as a dependency to event-stream in the same commit that established them as a maintainer. The dependency contained obfuscated, minified code that only activated under specific conditions.

Most code review processes focus on the diff. In this case, the diff looked reasonable — add a dependency, implement a flatmap helper. The malicious payload was inside the dependency, not the diff. Automated dependency risk scoring, combined with the contributor history signal, would have elevated this change to a threshold that demanded deeper scrutiny.

The ownership gap

The original maintainer was inactive. There was no CODEOWNERS file, no required reviewer, and no secondary approval required before publishing to npm. This is not unusual for open source projects — but it is a structural risk that shows up clearly in pre-merge analysis.

A CODEOWNERS file requiring sign-off from an established contributor creates a friction point — a required human step — that changes the economics of an attack.

What a score of 94 means in practice

In Koalr's model, scores above 75 trigger a warning. Scores above 85 block merge by default. A score of 94 would have surfaced a full signal breakdown before the dependency was committed.

The conversation that follows is not always "do not merge." Sometimes it is "we understand this risk and have mitigated it as follows." That conversation — the one where someone has to articulate why a first-time contributor with no history is adding an unvetted dependency to a package with 11 million weekly downloads — is the one that did not happen in 2018.

Risk scoring does not replace judgement. It forces the conversation before the damage is done, not two months after eight million downloads have already run the payload.

Why this matters beyond npm

The event-stream incident is often framed as an open source governance failure or a supply chain security problem. Both are true. But it is also a deployment risk story: a high-impact change was merged without adequate scrutiny because no tooling surfaced the risk clearly enough to stop it.

The same pattern appears in proprietary codebases every week. A new hire merges a change to a critical payment path. A contractor adds an unexpected dependency to an auth service. A recently-promoted maintainer ships directly to production on a Friday. The blast radius varies. The underlying failure — insufficient pre-merge risk visibility — is consistent.

See what Koalr flags on your own PRs

Install the GitHub App and every pull request gets a 0–100 risk score with a full signal breakdown. No signup form required.

Sources: event-stream issue #116 · Snyk post-mortem · Intrinsic analysis