supply-chain-guard 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +191 -0
- package/README.md +255 -0
- package/action.yml +152 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +139 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/npm-scanner.d.ts +14 -0
- package/dist/npm-scanner.d.ts.map +1 -0
- package/dist/npm-scanner.js +347 -0
- package/dist/npm-scanner.js.map +1 -0
- package/dist/patterns.d.ts +29 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +222 -0
- package/dist/patterns.js.map +1 -0
- package/dist/reporter.d.ts +10 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +224 -0
- package/dist/reporter.js.map +1 -0
- package/dist/scanner.d.ts +11 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +423 -0
- package/dist/scanner.js.map +1 -0
- package/dist/solana-monitor.d.ts +39 -0
- package/dist/solana-monitor.d.ts.map +1 -0
- package/dist/solana-monitor.js +246 -0
- package/dist/solana-monitor.js.map +1 -0
- package/dist/types.d.ts +108 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* supply-chain-guard CLI
|
|
5
|
+
*
|
|
6
|
+
* Scan code repositories, npm packages, and VS Code extensions
|
|
7
|
+
* for supply-chain malware indicators.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const commander_1 = require("commander");
|
|
11
|
+
const scanner_js_1 = require("./scanner.js");
|
|
12
|
+
const npm_scanner_js_1 = require("./npm-scanner.js");
|
|
13
|
+
const solana_monitor_js_1 = require("./solana-monitor.js");
|
|
14
|
+
const reporter_js_1 = require("./reporter.js");
|
|
15
|
+
const program = new commander_1.Command();
|
|
16
|
+
program
|
|
17
|
+
.name("supply-chain-guard")
|
|
18
|
+
.description("Open-source supply-chain security scanner. Detects GlassWorm and similar malware campaigns in npm packages, code repos, and VS Code extensions.")
|
|
19
|
+
.version("1.0.0");
|
|
20
|
+
// ── scan command ────────────────────────────────────────────────────
|
|
21
|
+
program
|
|
22
|
+
.command("scan")
|
|
23
|
+
.description("Scan a local directory or GitHub repo for malware indicators")
|
|
24
|
+
.argument("<target>", "Local directory path or GitHub repo URL")
|
|
25
|
+
.option("-f, --format <format>", "Output format: text, json, markdown", "text")
|
|
26
|
+
.option("-s, --min-severity <severity>", "Minimum severity to report: critical, high, medium, low, info")
|
|
27
|
+
.option("-e, --exclude <rules>", "Comma-separated list of rule IDs to exclude")
|
|
28
|
+
.option("-d, --depth <depth>", "Maximum directory depth", "20")
|
|
29
|
+
.action(async (target, opts) => {
|
|
30
|
+
try {
|
|
31
|
+
const options = {
|
|
32
|
+
target,
|
|
33
|
+
format: opts.format,
|
|
34
|
+
minSeverity: opts.minSeverity,
|
|
35
|
+
excludeRules: opts.exclude?.split(",").map((r) => r.trim()),
|
|
36
|
+
maxDepth: parseInt(opts.depth, 10),
|
|
37
|
+
};
|
|
38
|
+
const report = await (0, scanner_js_1.scan)(options);
|
|
39
|
+
console.log((0, reporter_js_1.formatReport)(report, options.format));
|
|
40
|
+
// Exit with non-zero if critical findings
|
|
41
|
+
if (report.summary.critical > 0) {
|
|
42
|
+
process.exit(2);
|
|
43
|
+
}
|
|
44
|
+
if (report.summary.high > 0) {
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
50
|
+
console.error(`\n Error: ${message}\n`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// ── npm command ─────────────────────────────────────────────────────
|
|
55
|
+
program
|
|
56
|
+
.command("npm")
|
|
57
|
+
.description("Scan an npm package for malware indicators (downloads without installing)")
|
|
58
|
+
.argument("<package>", "npm package name (e.g., express, lodash)")
|
|
59
|
+
.option("-f, --format <format>", "Output format: text, json, markdown", "text")
|
|
60
|
+
.option("-s, --min-severity <severity>", "Minimum severity to report")
|
|
61
|
+
.action(async (packageName, opts) => {
|
|
62
|
+
try {
|
|
63
|
+
const report = await (0, npm_scanner_js_1.scanNpmPackage)(packageName, {
|
|
64
|
+
target: packageName,
|
|
65
|
+
format: opts.format,
|
|
66
|
+
minSeverity: opts.minSeverity,
|
|
67
|
+
});
|
|
68
|
+
console.log((0, reporter_js_1.formatReport)(report, opts.format));
|
|
69
|
+
if (report.summary.critical > 0) {
|
|
70
|
+
process.exit(2);
|
|
71
|
+
}
|
|
72
|
+
if (report.summary.high > 0) {
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
78
|
+
console.error(`\n Error: ${message}\n`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// ── monitor command ─────────────────────────────────────────────────
|
|
83
|
+
program
|
|
84
|
+
.command("monitor")
|
|
85
|
+
.description("Monitor a Solana wallet for C2 memo transactions")
|
|
86
|
+
.argument("<address>", "Solana wallet address to monitor")
|
|
87
|
+
.option("-i, --interval <seconds>", "Polling interval in seconds", "30")
|
|
88
|
+
.option("-l, --limit <count>", "Max transactions per poll", "20")
|
|
89
|
+
.option("-f, --format <format>", "Output format: text, json", "text")
|
|
90
|
+
.option("--once", "Check once and exit (no continuous monitoring)")
|
|
91
|
+
.action(async (address, opts) => {
|
|
92
|
+
try {
|
|
93
|
+
if (opts.once) {
|
|
94
|
+
// One-shot check
|
|
95
|
+
const results = await (0, solana_monitor_js_1.checkWallet)(address, parseInt(opts.limit, 10));
|
|
96
|
+
if (opts.format === "json") {
|
|
97
|
+
console.log(JSON.stringify(results, null, 2));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
if (results.length === 0) {
|
|
101
|
+
console.log("\n No memo transactions found.\n");
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.log(`\n Found ${results.length} memo transaction(s):\n`);
|
|
105
|
+
for (const tx of results) {
|
|
106
|
+
console.log(` Signature: ${tx.signature}`);
|
|
107
|
+
console.log(` Memos: ${tx.memos.join(", ")}`);
|
|
108
|
+
if (tx.blockTime) {
|
|
109
|
+
console.log(` Time: ${new Date(tx.blockTime * 1000).toISOString()}`);
|
|
110
|
+
}
|
|
111
|
+
console.log("");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// Continuous monitoring
|
|
118
|
+
await (0, solana_monitor_js_1.monitorWallet)({
|
|
119
|
+
address,
|
|
120
|
+
interval: parseInt(opts.interval, 10),
|
|
121
|
+
limit: parseInt(opts.limit, 10),
|
|
122
|
+
format: opts.format,
|
|
123
|
+
}, (alert) => {
|
|
124
|
+
if (opts.format === "json") {
|
|
125
|
+
console.log(JSON.stringify(alert, null, 2));
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
console.log((0, solana_monitor_js_1.formatAlert)(alert));
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
134
|
+
console.error(`\n Error: ${message}\n`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
program.parse();
|
|
139
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* supply-chain-guard
|
|
3
|
+
*
|
|
4
|
+
* Open-source supply-chain security scanner for npm, PyPI, and VS Code extensions.
|
|
5
|
+
* Detects GlassWorm and similar malware campaigns.
|
|
6
|
+
*/
|
|
7
|
+
export { scan } from "./scanner.js";
|
|
8
|
+
export { scanNpmPackage } from "./npm-scanner.js";
|
|
9
|
+
export { monitorWallet, checkWallet, formatAlert } from "./solana-monitor.js";
|
|
10
|
+
export { formatReport } from "./reporter.js";
|
|
11
|
+
export type { Finding, ScanReport, ScanOptions, ScanSummary, Severity, NpmPackageInfo, SolanaMonitorOptions, SolanaTransaction, PatternEntry, } from "./types.js";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,GACb,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* supply-chain-guard
|
|
4
|
+
*
|
|
5
|
+
* Open-source supply-chain security scanner for npm, PyPI, and VS Code extensions.
|
|
6
|
+
* Detects GlassWorm and similar malware campaigns.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.formatReport = exports.formatAlert = exports.checkWallet = exports.monitorWallet = exports.scanNpmPackage = exports.scan = void 0;
|
|
10
|
+
var scanner_js_1 = require("./scanner.js");
|
|
11
|
+
Object.defineProperty(exports, "scan", { enumerable: true, get: function () { return scanner_js_1.scan; } });
|
|
12
|
+
var npm_scanner_js_1 = require("./npm-scanner.js");
|
|
13
|
+
Object.defineProperty(exports, "scanNpmPackage", { enumerable: true, get: function () { return npm_scanner_js_1.scanNpmPackage; } });
|
|
14
|
+
var solana_monitor_js_1 = require("./solana-monitor.js");
|
|
15
|
+
Object.defineProperty(exports, "monitorWallet", { enumerable: true, get: function () { return solana_monitor_js_1.monitorWallet; } });
|
|
16
|
+
Object.defineProperty(exports, "checkWallet", { enumerable: true, get: function () { return solana_monitor_js_1.checkWallet; } });
|
|
17
|
+
Object.defineProperty(exports, "formatAlert", { enumerable: true, get: function () { return solana_monitor_js_1.formatAlert; } });
|
|
18
|
+
var reporter_js_1 = require("./reporter.js");
|
|
19
|
+
Object.defineProperty(exports, "formatReport", { enumerable: true, get: function () { return reporter_js_1.formatReport; } });
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,2CAAoC;AAA3B,kGAAA,IAAI,OAAA;AACb,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,yDAA8E;AAArE,kHAAA,aAAa,OAAA;AAAE,gHAAA,WAAW,OAAA;AAAE,gHAAA,WAAW,OAAA;AAChD,6CAA6C;AAApC,2GAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npm package scanner
|
|
3
|
+
*
|
|
4
|
+
* Downloads and analyzes npm packages without installing them.
|
|
5
|
+
* Checks for suspicious scripts, obfuscated code, and known malicious patterns.
|
|
6
|
+
*/
|
|
7
|
+
import type { ScanReport, ScanOptions } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Scan an npm package by name.
|
|
10
|
+
*/
|
|
11
|
+
export declare function scanNpmPackage(packageName: string, options: Omit<ScanOptions, "target"> & {
|
|
12
|
+
target?: string;
|
|
13
|
+
}): Promise<ScanReport>;
|
|
14
|
+
//# sourceMappingURL=npm-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-scanner.d.ts","sourceRoot":"","sources":["../src/npm-scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAA2B,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA0BnF;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD,OAAO,CAAC,UAAU,CAAC,CAsErB"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* npm package scanner
|
|
4
|
+
*
|
|
5
|
+
* Downloads and analyzes npm packages without installing them.
|
|
6
|
+
* Checks for suspicious scripts, obfuscated code, and known malicious patterns.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.scanNpmPackage = scanNpmPackage;
|
|
43
|
+
const fs = __importStar(require("node:fs"));
|
|
44
|
+
const path = __importStar(require("node:path"));
|
|
45
|
+
const https = __importStar(require("node:https"));
|
|
46
|
+
const node_child_process_1 = require("node:child_process");
|
|
47
|
+
const types_js_1 = require("./types.js");
|
|
48
|
+
const patterns_js_1 = require("./patterns.js");
|
|
49
|
+
const TOOL_VERSION = "1.0.0";
|
|
50
|
+
const NPM_REGISTRY = "https://registry.npmjs.org";
|
|
51
|
+
/**
|
|
52
|
+
* Scan an npm package by name.
|
|
53
|
+
*/
|
|
54
|
+
async function scanNpmPackage(packageName, options) {
|
|
55
|
+
const startTime = Date.now();
|
|
56
|
+
const findings = [];
|
|
57
|
+
// Check package name against known malicious patterns
|
|
58
|
+
checkPackageName(packageName, findings);
|
|
59
|
+
// Fetch package metadata from registry
|
|
60
|
+
const metadata = await fetchPackageMetadata(packageName);
|
|
61
|
+
const latestVersion = metadata["dist-tags"]?.latest;
|
|
62
|
+
if (!latestVersion) {
|
|
63
|
+
throw new Error(`Could not determine latest version for ${packageName}`);
|
|
64
|
+
}
|
|
65
|
+
const versionData = metadata.versions?.[latestVersion];
|
|
66
|
+
if (!versionData) {
|
|
67
|
+
throw new Error(`Version data not found for ${packageName}@${latestVersion}`);
|
|
68
|
+
}
|
|
69
|
+
// Check package.json scripts
|
|
70
|
+
checkPackageScripts(versionData, findings);
|
|
71
|
+
// Check dependencies against known malicious packages
|
|
72
|
+
checkDependencies(versionData, findings);
|
|
73
|
+
// Download and scan tarball
|
|
74
|
+
const tarballUrl = versionData.dist?.tarball;
|
|
75
|
+
if (tarballUrl) {
|
|
76
|
+
await downloadAndScanTarball(tarballUrl, findings);
|
|
77
|
+
}
|
|
78
|
+
// Calculate results
|
|
79
|
+
const summary = {
|
|
80
|
+
totalFiles: 0,
|
|
81
|
+
filesScanned: 0,
|
|
82
|
+
critical: findings.filter((f) => f.severity === "critical").length,
|
|
83
|
+
high: findings.filter((f) => f.severity === "high").length,
|
|
84
|
+
medium: findings.filter((f) => f.severity === "medium").length,
|
|
85
|
+
low: findings.filter((f) => f.severity === "low").length,
|
|
86
|
+
info: findings.filter((f) => f.severity === "info").length,
|
|
87
|
+
};
|
|
88
|
+
let score = 0;
|
|
89
|
+
for (const finding of findings) {
|
|
90
|
+
score += types_js_1.SEVERITY_SCORES[finding.severity];
|
|
91
|
+
}
|
|
92
|
+
score = Math.min(100, score);
|
|
93
|
+
const riskLevel = score === 0
|
|
94
|
+
? "clean"
|
|
95
|
+
: score <= 10
|
|
96
|
+
? "low"
|
|
97
|
+
: score <= 30
|
|
98
|
+
? "medium"
|
|
99
|
+
: score <= 60
|
|
100
|
+
? "high"
|
|
101
|
+
: "critical";
|
|
102
|
+
return {
|
|
103
|
+
tool: `supply-chain-guard v${TOOL_VERSION}`,
|
|
104
|
+
timestamp: new Date().toISOString(),
|
|
105
|
+
target: `${packageName}@${latestVersion}`,
|
|
106
|
+
scanType: "npm",
|
|
107
|
+
durationMs: Date.now() - startTime,
|
|
108
|
+
findings,
|
|
109
|
+
summary,
|
|
110
|
+
score,
|
|
111
|
+
riskLevel,
|
|
112
|
+
recommendations: generateNpmRecommendations(findings, packageName),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check if the package name matches known malicious patterns.
|
|
117
|
+
*/
|
|
118
|
+
function checkPackageName(name, findings) {
|
|
119
|
+
for (const pattern of patterns_js_1.MALICIOUS_PACKAGE_PATTERNS) {
|
|
120
|
+
const regex = new RegExp(pattern);
|
|
121
|
+
if (regex.test(name)) {
|
|
122
|
+
findings.push({
|
|
123
|
+
rule: "MALICIOUS_PACKAGE_NAME",
|
|
124
|
+
description: `Package name "${name}" matches a known malicious or typosquatting pattern`,
|
|
125
|
+
severity: "high",
|
|
126
|
+
recommendation: `Verify this is the package you intended to use. Known typosquatting packages exist with similar names.`,
|
|
127
|
+
});
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check package.json scripts for suspicious entries.
|
|
134
|
+
*/
|
|
135
|
+
function checkPackageScripts(pkg, findings) {
|
|
136
|
+
const scripts = pkg.scripts;
|
|
137
|
+
if (!scripts)
|
|
138
|
+
return;
|
|
139
|
+
const dangerousHooks = ["preinstall", "postinstall", "preuninstall", "postuninstall"];
|
|
140
|
+
for (const hook of dangerousHooks) {
|
|
141
|
+
const script = scripts[hook];
|
|
142
|
+
if (!script)
|
|
143
|
+
continue;
|
|
144
|
+
for (const pattern of patterns_js_1.SUSPICIOUS_SCRIPTS) {
|
|
145
|
+
const regex = new RegExp(pattern.pattern, "i");
|
|
146
|
+
if (regex.test(script)) {
|
|
147
|
+
findings.push({
|
|
148
|
+
rule: pattern.rule,
|
|
149
|
+
description: `npm ${hook}: ${pattern.description}`,
|
|
150
|
+
severity: pattern.severity,
|
|
151
|
+
file: "package.json",
|
|
152
|
+
match: `${hook}: ${script}`,
|
|
153
|
+
recommendation: `Review the ${hook} script before installing this package.`,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check dependencies against known malicious package patterns.
|
|
161
|
+
*/
|
|
162
|
+
function checkDependencies(pkg, findings) {
|
|
163
|
+
const allDeps = [];
|
|
164
|
+
const deps = pkg.dependencies;
|
|
165
|
+
const devDeps = pkg.devDependencies;
|
|
166
|
+
if (deps)
|
|
167
|
+
allDeps.push(...Object.keys(deps));
|
|
168
|
+
if (devDeps)
|
|
169
|
+
allDeps.push(...Object.keys(devDeps));
|
|
170
|
+
for (const dep of allDeps) {
|
|
171
|
+
for (const pattern of patterns_js_1.MALICIOUS_PACKAGE_PATTERNS) {
|
|
172
|
+
const regex = new RegExp(pattern);
|
|
173
|
+
if (regex.test(dep)) {
|
|
174
|
+
findings.push({
|
|
175
|
+
rule: "MALICIOUS_DEPENDENCY",
|
|
176
|
+
description: `Dependency "${dep}" matches a known malicious or typosquatting pattern`,
|
|
177
|
+
severity: "high",
|
|
178
|
+
file: "package.json",
|
|
179
|
+
recommendation: `Verify that "${dep}" is a legitimate package and not a typosquat.`,
|
|
180
|
+
});
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Fetch package metadata from the npm registry.
|
|
188
|
+
*/
|
|
189
|
+
async function fetchPackageMetadata(packageName) {
|
|
190
|
+
const url = `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`;
|
|
191
|
+
return new Promise((resolve, reject) => {
|
|
192
|
+
https
|
|
193
|
+
.get(url, { headers: { Accept: "application/json" } }, (res) => {
|
|
194
|
+
if (res.statusCode === 404) {
|
|
195
|
+
reject(new Error(`Package not found: ${packageName}`));
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (res.statusCode !== 200) {
|
|
199
|
+
reject(new Error(`npm registry returned status ${res.statusCode} for ${packageName}`));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
let data = "";
|
|
203
|
+
res.on("data", (chunk) => {
|
|
204
|
+
data += chunk.toString();
|
|
205
|
+
});
|
|
206
|
+
res.on("end", () => {
|
|
207
|
+
try {
|
|
208
|
+
resolve(JSON.parse(data));
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
reject(new Error("Failed to parse npm registry response"));
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
})
|
|
215
|
+
.on("error", reject);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Download tarball and scan its contents.
|
|
220
|
+
*/
|
|
221
|
+
async function downloadAndScanTarball(tarballUrl, findings) {
|
|
222
|
+
const tempDir = fs.mkdtempSync(path.join("/tmp", "scg-npm-"));
|
|
223
|
+
const tarballPath = path.join(tempDir, "package.tgz");
|
|
224
|
+
try {
|
|
225
|
+
// Download tarball
|
|
226
|
+
await downloadFile(tarballUrl, tarballPath);
|
|
227
|
+
// Extract tarball
|
|
228
|
+
const extractDir = path.join(tempDir, "extracted");
|
|
229
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
230
|
+
(0, node_child_process_1.execSync)(`tar xzf "${tarballPath}" -C "${extractDir}"`, { stdio: "pipe" });
|
|
231
|
+
// Scan extracted files
|
|
232
|
+
const files = collectFilesRecursive(extractDir);
|
|
233
|
+
for (const filePath of files) {
|
|
234
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
235
|
+
if (!patterns_js_1.SCANNABLE_EXTENSIONS.has(ext))
|
|
236
|
+
continue;
|
|
237
|
+
const stat = fs.statSync(filePath);
|
|
238
|
+
if (stat.size > patterns_js_1.MAX_FILE_SIZE)
|
|
239
|
+
continue;
|
|
240
|
+
try {
|
|
241
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
242
|
+
const relativePath = path.relative(extractDir, filePath);
|
|
243
|
+
for (const pattern of patterns_js_1.FILE_PATTERNS) {
|
|
244
|
+
const regex = new RegExp(pattern.pattern, "g");
|
|
245
|
+
const lines = content.split("\n");
|
|
246
|
+
for (let i = 0; i < lines.length; i++) {
|
|
247
|
+
const match = regex.exec(lines[i] ?? "");
|
|
248
|
+
if (match) {
|
|
249
|
+
findings.push({
|
|
250
|
+
rule: pattern.rule,
|
|
251
|
+
description: pattern.description,
|
|
252
|
+
severity: pattern.severity,
|
|
253
|
+
file: relativePath,
|
|
254
|
+
line: i + 1,
|
|
255
|
+
match: match[0].substring(0, 120),
|
|
256
|
+
recommendation: `Found in published npm tarball. ${pattern.description}`,
|
|
257
|
+
});
|
|
258
|
+
regex.lastIndex = 0;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Skip unreadable files
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
finally {
|
|
269
|
+
// Cleanup
|
|
270
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Download a file from a URL.
|
|
275
|
+
*/
|
|
276
|
+
function downloadFile(url, dest) {
|
|
277
|
+
return new Promise((resolve, reject) => {
|
|
278
|
+
const file = fs.createWriteStream(dest);
|
|
279
|
+
https
|
|
280
|
+
.get(url, (response) => {
|
|
281
|
+
// Handle redirects
|
|
282
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
283
|
+
const redirectUrl = response.headers.location;
|
|
284
|
+
if (redirectUrl) {
|
|
285
|
+
file.close();
|
|
286
|
+
downloadFile(redirectUrl, dest).then(resolve, reject);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
response.pipe(file);
|
|
291
|
+
file.on("finish", () => {
|
|
292
|
+
file.close();
|
|
293
|
+
resolve();
|
|
294
|
+
});
|
|
295
|
+
})
|
|
296
|
+
.on("error", (err) => {
|
|
297
|
+
fs.unlinkSync(dest);
|
|
298
|
+
reject(err);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Recursively collect files.
|
|
304
|
+
*/
|
|
305
|
+
function collectFilesRecursive(dir) {
|
|
306
|
+
const files = [];
|
|
307
|
+
let entries;
|
|
308
|
+
try {
|
|
309
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
return files;
|
|
313
|
+
}
|
|
314
|
+
for (const entry of entries) {
|
|
315
|
+
const fullPath = path.join(dir, entry.name);
|
|
316
|
+
if (entry.isDirectory() && entry.name !== "node_modules") {
|
|
317
|
+
files.push(...collectFilesRecursive(fullPath));
|
|
318
|
+
}
|
|
319
|
+
else if (entry.isFile()) {
|
|
320
|
+
files.push(fullPath);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return files;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Generate recommendations for npm package scan.
|
|
327
|
+
*/
|
|
328
|
+
function generateNpmRecommendations(findings, packageName) {
|
|
329
|
+
const recommendations = [];
|
|
330
|
+
if (findings.some((f) => f.rule === "MALICIOUS_PACKAGE_NAME")) {
|
|
331
|
+
recommendations.push(`The package name "${packageName}" matches known malicious patterns. Verify this is the intended package.`);
|
|
332
|
+
}
|
|
333
|
+
if (findings.some((f) => f.rule.startsWith("SCRIPT_"))) {
|
|
334
|
+
recommendations.push("Suspicious install scripts detected. Use --ignore-scripts when installing: npm install --ignore-scripts");
|
|
335
|
+
}
|
|
336
|
+
if (findings.some((f) => f.severity === "critical")) {
|
|
337
|
+
recommendations.push("CRITICAL findings detected. Do NOT install this package until the findings are investigated.");
|
|
338
|
+
}
|
|
339
|
+
if (findings.some((f) => f.rule === "MALICIOUS_DEPENDENCY")) {
|
|
340
|
+
recommendations.push("This package depends on packages matching known malicious patterns. Audit the full dependency tree.");
|
|
341
|
+
}
|
|
342
|
+
if (findings.length === 0) {
|
|
343
|
+
recommendations.push(`No malicious indicators found in ${packageName}. The package appears safe based on known patterns.`);
|
|
344
|
+
}
|
|
345
|
+
return recommendations;
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=npm-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-scanner.js","sourceRoot":"","sources":["../src/npm-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Known malicious patterns database
|
|
3
|
+
*
|
|
4
|
+
* This file is designed to be regularly updated as new threats emerge.
|
|
5
|
+
* Add new patterns, wallet addresses, or domain patterns as they are discovered.
|
|
6
|
+
*/
|
|
7
|
+
import type { PatternEntry, Severity } from "./types.js";
|
|
8
|
+
/** Known GlassWorm marker variables */
|
|
9
|
+
export declare const GLASSWORM_MARKERS: string[];
|
|
10
|
+
/** Known GlassWorm Solana wallet addresses used for C2 */
|
|
11
|
+
export declare const KNOWN_C2_WALLETS: string[];
|
|
12
|
+
/** Known C2 domain patterns (regex strings) */
|
|
13
|
+
export declare const C2_DOMAIN_PATTERNS: string[];
|
|
14
|
+
export declare const FILE_PATTERNS: PatternEntry[];
|
|
15
|
+
/** Files that are suspicious by name alone */
|
|
16
|
+
export declare const SUSPICIOUS_FILES: Array<{
|
|
17
|
+
pattern: string;
|
|
18
|
+
description: string;
|
|
19
|
+
severity: Severity;
|
|
20
|
+
rule: string;
|
|
21
|
+
}>;
|
|
22
|
+
/** Package.json script patterns that are suspicious */
|
|
23
|
+
export declare const SUSPICIOUS_SCRIPTS: PatternEntry[];
|
|
24
|
+
/** Patterns matching known malicious or typosquatting package names */
|
|
25
|
+
export declare const MALICIOUS_PACKAGE_PATTERNS: string[];
|
|
26
|
+
export declare const SCANNABLE_EXTENSIONS: Set<string>;
|
|
27
|
+
/** Maximum file size to scan (in bytes). Files larger than this are skipped. */
|
|
28
|
+
export declare const MAX_FILE_SIZE: number;
|
|
29
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAMzD,uCAAuC;AACvC,eAAO,MAAM,iBAAiB,UAAsB,CAAC;AAErD,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,EAAE,MAAM,EAGpC,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,EAAE,MAAM,EAItC,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,YAAY,EAkHvC,CAAC;AAMF,8CAA8C;AAC9C,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAeA,CAAC;AAMF,uDAAuD;AACvD,eAAO,MAAM,kBAAkB,EAAE,YAAY,EAqC5C,CAAC;AAMF,uEAAuE;AACvE,eAAO,MAAM,0BAA0B,EAAE,MAAM,EAY9C,CAAC;AAMF,eAAO,MAAM,oBAAoB,aAc/B,CAAC;AAEH,gFAAgF;AAChF,eAAO,MAAM,aAAa,QAAkB,CAAC"}
|