Skip to content

Instantly share code, notes, and snippets.

@koad
Created September 9, 2025 14:51
Show Gist options
  • Select an option

  • Save koad/e64f858fa74013d72c512cf642b8f0a7 to your computer and use it in GitHub Desktop.

Select an option

Save koad/e64f858fa74013d72c512cf642b8f0a7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
/**
* condom.js — guardrail for npm supply chain incident
* Exits if any known-compromised package@version is detected.
*/
const { execSync } = require("child_process");
const banned = {
"ansi-regex": "6.2.1",
"ansi-styles": "6.2.2",
"backslash": "0.2.1",
"chalk": "5.6.1",
"chalk-template": "1.1.1",
"color-convert": "3.1.1",
"color-name": "2.0.1",
"color-string": "2.1.1",
"debug": "4.4.2",
"error-ex": "1.3.3",
"has-ansi": "6.0.1",
"is-arrayish": "0.3.3",
"proto-tinker-wc": "1.8.7",
"supports-hyperlinks": "4.1.1",
"simple-swizzle": "0.2.3",
"slice-ansi": "7.1.1",
"strip-ansi": "7.1.1",
"supports-color": "10.2.1",
"wrap-ansi": "9.0.1"
};
function checkDeps() {
try {
const output = execSync("npm ls --depth=Infinity --json", { stdio: ["pipe", "pipe", "ignore"] });
const tree = JSON.parse(output);
const problems = [];
function walk(deps) {
if (!deps) return;
for (const [name, info] of Object.entries(deps)) {
if (banned[name] && info.version === banned[name]) {
problems.push(`${name}@${info.version}`);
}
walk(info.dependencies);
}
}
walk(tree.dependencies);
if (problems.length) {
console.error("\n🚨 Infected package versions detected:\n");
problems.forEach(p => console.error(" - " + p));
console.error("\n❌ Aborting startup. Please pin safe versions.\n");
process.exit(1);
}
} catch (err) {
console.error("condom.js failed to run `npm ls`:", err.message);
process.exit(2);
}
}
checkDeps();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment