On January 5, 2022, npm maintainer Marak Squires force-pushed a commit to the faker.js repository that deleted every file in the project and replaced it with a one-line README asking "What really happened with Aaron Swartz?" He tagged the wreckage version 6.6.6. Three days later, on January 8, 2022, he pushed a sabotaged update to colors.js — version 1.4.44-liberty-2 — that buried an infinite loop in the source, printing the word "LIBERTY" and an ASCII flag to the console forever, freezing any Node.js process that loaded it. Squires maintained both packages. Faker.js had 2.4 million weekly downloads and roughly 2,500 dependent projects; colors.js had 23 million weekly downloads and nearly 19,000. Within hours, CI pipelines across the internet started failing. This is the incident that gave the security industry a new word: protestware.
What is protestware, and why do colors.js and faker.js define the term?
Protestware is open-source code intentionally broken or weaponized by its own maintainer to make a political or economic point, and colors.js/faker.js is the case that put the word in every vendor's vocabulary. Unlike a supply chain attack where a third party steals credentials or slips in a backdoor, protestware comes from the trusted source itself — the person npm, GitHub, and every downstream package.json already trusted with commit access. Before January 2022, most dependency risk models assumed the threat was external (typosquatting, dependency confusion, stolen npm tokens). Squires proved the threat could be the maintainer of record, acting entirely within his rights to modify code he legally owned, with zero code review required because he was the sole maintainer.
What exactly did Marak Squires do to colors.js and faker.js?
He shipped destructive code disguised as ordinary version bumps, so nothing looked unusual in a diff until it executed. For faker.js, the sabotage was a force-push that erased the entire git history and source tree, published to npm as 6.6.6 — a version number that made the intent unmistakable. For colors.js, the sabotage was subtler and arguably more damaging in production: version 1.4.44-liberty-2 (and a related 1.4.1 tag) added a self-invoking function that entered an infinite loop the moment the package was require()'d, printing non-ASCII "LIBERTY" banners and hanging the process. Because colors.js is a formatting utility pulled in transitively by build tools, CLIs, and test harnesses, teams that had never heard of colors.js watched their deploys hang with no obvious culprit in their own code.
Why did Squires sabotage his own widely used packages?
He said it was retaliation for years of uncompensated labor propping up commercial software. In a since-removed GitHub Issues post from November 2020, Squires told users he was "no longer going to support Fortune 500s (and other smaller sized companies) with my free work" and suggested corporate users either fork his projects or pay him a six-figure annual contract. Fourteen months of no meaningful response from the corporations relying on his code preceded the January 2022 sabotage. Whatever the merits of the grievance — and the underdiscussed labor economics of open source were real — the method he chose turned a compensation dispute into a denial-of-service incident affecting people who had no idea colors.js existed in their dependency tree.
How many projects and companies were actually affected?
Enough that "colors.js broke my build" trended on developer Twitter and Hacker News within a day. Because colors.js sat in the dependency graph of nearly 19,000 packages, the blast radius extended far past direct consumers — Amazon's Cloud Development Kit (AWS CDK) was among the widely reported casualties, along with countless internal CI jobs, Docker builds, and test suites that silently hung instead of failing fast. Faker.js's smaller footprint (about 2,500 dependents) still meant thousands of test suites that generated mock data suddenly had no library to call. Neither package shipped a CVE in the traditional sense at first; the industry had to retroactively classify the incident as a supply chain risk because existing vulnerability databases had no category for "maintainer intentionally destroys own package."
How is protestware different from a conventional supply chain attack?
Protestware is authorized sabotage, while a conventional supply chain attack is unauthorized intrusion — and that distinction is exactly why it's harder to defend against with traditional access controls. Two months after colors.js, in March 2022, node-ipc maintainer Brandon Nozaki Miller (RIAEvangelist) added a dependency called "peacenotwar" that detected Russian and Belarusian IP geolocations and overwrote files on those machines in protest of the invasion of Ukraine — a case Snyk and GitHub both flagged as malicious, since node-ipc shipped inside Vue CLI's dependency tree at the time. Compare that to the 2018 event-stream incident, where an attacker socially engineered maintainer access away from the real owner and then quietly inserted a Bitcoin-stealing payload — a classic account-takeover supply chain attack. Protestware needs no stolen credentials, no phishing email, and no code review bypass, because the person doing the damage already has full, legitimate write access. Signature verification, 2FA, and provenance attestations — the standard defenses against account takeover — do nothing to stop a maintainer sabotaging their own package on purpose.
What did npm, GitHub, and the ecosystem do in response?
GitHub suspended Squires's account and npm reverted colors.js and faker.js to their last known-good versions (colors.js to 1.4.0, faker.js to a pre-sabotage fork). The faker.js community forked the project within days into what became @faker-js/faker, now the maintained successor with its own release cadence and governance separate from Squires. The incident became a direct talking point in npm's push toward package provenance (cryptographically signed build attestations, GA in 2023) and in renewed industry interest in software bills of materials (SBOMs) as a way to know, before a build breaks, exactly which transitive packages — and which maintainers — sit in a given deployment. It also pushed more teams toward pinned lockfile versions and private registry mirroring rather than trusting ^ semver ranges to always resolve safely.
How Safeguard Helps
Protestware and self-sabotage incidents like colors.js and faker.js expose the blind spot in dependency management: teams often don't know a risky package is in their build until it's already hung a pipeline or shipped to production. Safeguard's SBOM generation and ingest give you a live, queryable inventory of every transitive dependency — including deep, indirect ones like colors.js — so a maintainer-level incident surfaces as an alert instead of a mystery outage. Reachability analysis then tells you whether the sabotaged or vulnerable code path is actually called by your application, cutting through noisy transitive-dependency alerts to the handful that matter. Griffin AI correlates that reachability data with maintainer and package-health signals to flag anomalous releases — like a version-number tag of 6.6.6 or a sudden force-push wiping history — before they hit your build. And when a fix is available, such as pinning to @faker-js/faker or colors.js 1.4.0, Safeguard opens an auto-fix pull request so the remediation ships in minutes, not the hours it took thousands of teams to triage this incident by hand.