War, Sanctions, and Open-Source Supply Chains
· Jerwin Arnado
Archive note: this is a backdated post, written years later while rebuilding this site. It’s dated to the moment it covers, but the hindsight is real.
Russia invaded Ukraine on February 24, and within weeks the war reached a place nobody’s threat model included: the npm registry.
In March, the maintainer of node-ipc — a dependency pulled millions of times a week, sitting under tooling like Vue CLI — shipped a version containing protestware: code that checked the machine’s IP geolocation and, for users in Russia or Belarus, overwrote files with heart emojis. Later versions toned it down to dropping a “peacenotwar” message file on desktops. The damage to machines was one thing; the damage to assumptions was bigger.
And this wasn’t even the year’s first incident. Back in January, the maintainer of colors.js and faker.js — his own packages — pushed releases with infinite loops, partly in protest of corporations profiting from unpaid maintenance. Two months, two demonstrations of the same fact from opposite directions.
The fact being demonstrated
Every npm install and composer install is an act of trust in hundreds of strangers — not their code, which you could in principle audit, but their future behavior, which you cannot. Log4Shell taught us that a dependency can be accidentally dangerous. 2022’s lesson is sharper: a dependency can become deliberately dangerous, overnight, for reasons that have nothing to do with software — a war, a burnout, a grievance, a hijacked account.
“Supply chain” is the wrong metaphor, really. Supply chains have contracts and liability. This is closer to a potluck the whole industry eats from daily.
What actually protects you
Concrete practices, in the order they earn their keep:
- Lockfiles are a security boundary — commit them, respect them.
composer.lockandpackage-lock.jsonmean you install the exact bytes you tested, not whatever was published last night. The node-ipc payload reached people through floating version ranges. CI that runsnpm ci(notnpm install) andcomposer install(neverupdate) doesn’t get surprise versions. - Updates are a deliberate act, not a reflex. Review the diff or at least the changelog when bumping. Automated PRs from Dependabot are fine — auto-merging them is signing blank checks. A short quarantine period on brand-new releases costs little; most sabotage and hijack incidents get caught within days.
- Know your tree.
composer show --tree/npm lsoccasionally, and ask the awkward question: how many single-maintainer packages stand between your app and the world? You don’t need zero — you need to know. - Vendor what’s tiny. An 11-line left-pad-shaped utility is not worth a trust relationship with a stranger’s npm account. Copy it in (licenses permitting), own it forever.
- Pay or contribute where it counts. The deeper fix for the colors.js side of this: infrastructure maintained by exhausted volunteers will keep failing in human ways. If a package is load-bearing for your business, sponsorship is the cheapest insurance you’ll ever buy.
The uncomfortable nuance
I have sympathy in both directions here. The protest is against an invasion; the maintainers own their projects and owe us, contractually, nothing — every open-source license says so in capital letters (“AS IS”, no warranty). And yet: code that conditionally destroys user files based on geography is malware in any moral accounting, whatever its politics — and the people hit by IP geolocation aren’t governments, they’re random developers, NGOs included.
Both things are true, which is exactly the point. The open-source commons runs on a fragile, unwritten norm — packages don’t act against their users — and 2022 is showing us the norm is all there ever was. No registry policy fully fixes that. Trust carefully, pin everything, and be kind to maintainers; the entire stack is people.