Skip to content

Instantly share code, notes, and snippets.

@Santiago-j-s
Created September 8, 2025 21:02
Show Gist options
  • Select an option

  • Save Santiago-j-s/4201a2dbd4b91bc04f5e8e1e36385d4a to your computer and use it in GitHub Desktop.

Select an option

Save Santiago-j-s/4201a2dbd4b91bc04f5e8e1e36385d4a to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
import { execSync } from "child_process";
import { readFileSync } from "fs";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Vulnerable package versions from supply chain attack
const vulnerablePackages = [
"ansi-styles@6.2.2",
"debug@4.4.2",
"chalk@5.6.1",
"supports-color@10.2.1",
"strip-ansi@7.1.1",
"ansi-regex@6.2.1",
"wrap-ansi@9.0.1",
"color-convert@3.1.1",
"color-name@2.0.1",
"is-arrayish@0.3.3",
"slice-ansi@7.1.1",
"color@5.0.1",
"color-string@2.1.1",
"simple-swizzle@0.2.3",
"supports-hyperlinks@4.1.1",
"has-ansi@6.0.1",
"chalk-template@1.1.1",
"backslash@0.2.1",
];
// Colors for console output
const colors = {
reset: "\x1b[0m",
bright: "\x1b[1m",
red: "\x1b[31m",
green: "\x1b[32m",
yellow: "\x1b[33m",
blue: "\x1b[34m",
magenta: "\x1b[35m",
cyan: "\x1b[36m",
};
function colorize(text, color) {
return `${colors[color]}${text}${colors.reset}`;
}
function getAllInstalledPackages() {
try {
const packageLockPath = join(__dirname, "..", "package-lock.json");
const packageLock = JSON.parse(readFileSync(packageLockPath, "utf8"));
const installedPackages = {};
// Check all packages in package-lock.json
if (packageLock.packages) {
for (const [packagePath, packageData] of Object.entries(
packageLock.packages,
)) {
if (packagePath.startsWith("node_modules/")) {
const packageName = packagePath.replace("node_modules/", "");
installedPackages[packageName] = packageData.version;
}
}
}
return installedPackages;
} catch (error) {
console.error(
colorize("Error reading package-lock.json:", "red"),
error.message,
);
return {};
}
}
function checkNpmRegistry(packageName) {
try {
const result = execSync(`npm view ${packageName} version`, {
encoding: "utf8",
stdio: "pipe",
});
return result.trim();
} catch (error) {
return null;
}
}
function main() {
console.log(colorize("🚨 Supply Chain Attack Vulnerability Check\n", "red"));
console.log(
colorize(
"Checking for vulnerable package versions from supply chain attack...\n",
"yellow",
),
);
const installedPackages = getAllInstalledPackages();
const vulnerableFound = [];
const safeVersions = [];
console.log(colorize("Vulnerability Scan Results:", "bright"));
console.log(colorize("=".repeat(60), "red"));
for (const vulnerableSpec of vulnerablePackages) {
const [packageName, vulnerableVersion] = vulnerableSpec.split("@");
const installedVersion = installedPackages[packageName];
if (installedVersion) {
if (installedVersion === vulnerableVersion) {
// VULNERABLE VERSION FOUND!
vulnerableFound.push({ packageName, version: installedVersion });
console.log(
`\n${colorize("🚨 VULNERABLE", "red")} ${colorize(packageName, "bright")}:`,
);
console.log(
` ⚠️ Installed: ${colorize(installedVersion, "red")} ${colorize("(VULNERABLE!)", "red")}`,
);
console.log(` πŸ”’ Vulnerable: ${colorize(vulnerableVersion, "red")}`);
const latestVersion = checkNpmRegistry(packageName);
if (latestVersion) {
console.log(` βœ… Latest Safe: ${colorize(latestVersion, "green")}`);
console.log(` πŸ’‘ Action: Update to latest version immediately!`);
}
} else {
// Safe version installed
safeVersions.push({ packageName, version: installedVersion });
console.log(
`\n${colorize("βœ… SAFE", "green")} ${colorize(packageName, "bright")}:`,
);
console.log(` βœ… Installed: ${colorize(installedVersion, "green")}`);
console.log(` πŸ”’ Vulnerable: ${colorize(vulnerableVersion, "red")}`);
}
} else {
// Package not installed
console.log(
`\n${colorize("βž– NOT INSTALLED", "blue")} ${colorize(packageName, "bright")}:`,
);
console.log(` πŸ”’ Vulnerable: ${colorize(vulnerableVersion, "red")}`);
}
}
// Summary
console.log(`\n${colorize("=".repeat(60), "red")}`);
console.log(colorize("SUMMARY:", "bright"));
if (vulnerableFound.length > 0) {
console.log(`\n${colorize("🚨 VULNERABILITIES FOUND:", "red")}`);
vulnerableFound.forEach(({ packageName, version }) => {
console.log(
` β€’ ${colorize(packageName, "red")}@${colorize(version, "red")}`,
);
});
console.log(`\n${colorize("⚠️ IMMEDIATE ACTION REQUIRED:", "red")}`);
console.log(
` Run: npm update ${vulnerableFound.map((p) => p.packageName).join(" ")}`,
);
console.log(` Or: npm audit fix`);
} else {
console.log(`\n${colorize("βœ… NO VULNERABILITIES FOUND", "green")}`);
console.log(
` Your project is safe from these supply chain attack versions.`,
);
}
if (safeVersions.length > 0) {
console.log(`\n${colorize("βœ… Safe versions installed:", "green")}`);
safeVersions.forEach(({ packageName, version }) => {
console.log(
` β€’ ${colorize(packageName, "green")}@${colorize(version, "green")}`,
);
});
}
console.log(`\n${colorize("Check complete!", "cyan")}`);
// Exit with error code if vulnerabilities found
if (vulnerableFound.length > 0) {
process.exit(1);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment