npm-scan-plus 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/.eslintrc.json +32 -0
- package/.github/CODEOWNERS +3 -0
- package/.github/workflows/ci.yml +105 -0
- package/.prettierrc +10 -0
- package/FUNDING.yml +1 -0
- package/PLAN.md +151 -0
- package/README.md +150 -0
- package/bin/npm-scan +13 -0
- package/bin/npm-scan-wrap +100 -0
- package/dist/cli/index.d.ts +18 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +299 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/lib/blocklist.d.ts +45 -0
- package/dist/lib/blocklist.d.ts.map +1 -0
- package/dist/lib/blocklist.js +256 -0
- package/dist/lib/blocklist.js.map +1 -0
- package/dist/lib/extended.js +314 -0
- package/dist/lib/extended.js.map +1 -0
- package/dist/lib/integrity.js +247 -0
- package/dist/lib/integrity.js.map +1 -0
- package/dist/lib/patterns.d.ts +76 -0
- package/dist/lib/patterns.d.ts.map +1 -0
- package/dist/lib/patterns.js +414 -0
- package/dist/lib/patterns.js.map +1 -0
- package/dist/lib/registry.d.ts +42 -0
- package/dist/lib/registry.d.ts.map +1 -0
- package/dist/lib/registry.js +157 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/lib/scanner.d.ts +43 -0
- package/dist/lib/scanner.d.ts.map +1 -0
- package/dist/lib/scanner.js +432 -0
- package/dist/lib/scanner.js.map +1 -0
- package/dist/lib/vuln.js +284 -0
- package/dist/lib/vuln.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/jest.config.js +18 -0
- package/package.json +56 -0
- package/src/cli/index.ts +336 -0
- package/src/lib/blocklist.ts +239 -0
- package/src/lib/extended.ts +384 -0
- package/src/lib/integrity.ts +253 -0
- package/src/lib/patterns.ts +404 -0
- package/src/lib/registry.ts +146 -0
- package/src/lib/scanner.ts +447 -0
- package/src/lib/vuln.ts +321 -0
- package/src/types.ts +102 -0
- package/tests/blocklist.test.ts +89 -0
- package/tests/extended.test.ts +204 -0
- package/tests/patterns.test.ts +147 -0
- package/tests/scanner.test.ts +116 -0
- package/tests/vuln.test.ts +66 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLI entry point
|
|
4
|
+
* Pre and post-install npm security scanner
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.run = run;
|
|
8
|
+
exports.printHelp = printHelp;
|
|
9
|
+
const scanner_1 = require("../lib/scanner");
|
|
10
|
+
const blocklist_1 = require("../lib/blocklist");
|
|
11
|
+
/**
|
|
12
|
+
* Main CLI runner
|
|
13
|
+
*/
|
|
14
|
+
async function run(argv) {
|
|
15
|
+
const args = argv.slice(2);
|
|
16
|
+
const options = parseArgs(args);
|
|
17
|
+
if (!options.command) {
|
|
18
|
+
printHelp();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
switch (options.command) {
|
|
22
|
+
case 'pre':
|
|
23
|
+
await runPreInstall(options);
|
|
24
|
+
break;
|
|
25
|
+
case 'post':
|
|
26
|
+
await runPostInstall(options);
|
|
27
|
+
break;
|
|
28
|
+
case 'scan':
|
|
29
|
+
await runFullScan(options);
|
|
30
|
+
break;
|
|
31
|
+
case 'blocklist':
|
|
32
|
+
await runBlocklist(options);
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
printHelp();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Parse command line arguments
|
|
40
|
+
*/
|
|
41
|
+
function parseArgs(args) {
|
|
42
|
+
const options = {
|
|
43
|
+
command: 'scan'
|
|
44
|
+
};
|
|
45
|
+
let i = 0;
|
|
46
|
+
while (i < args.length) {
|
|
47
|
+
const arg = args[i];
|
|
48
|
+
switch (arg) {
|
|
49
|
+
case 'pre':
|
|
50
|
+
case 'post':
|
|
51
|
+
case 'scan':
|
|
52
|
+
case 'blocklist':
|
|
53
|
+
options.command = arg;
|
|
54
|
+
break;
|
|
55
|
+
case 'install':
|
|
56
|
+
options.command = 'pre';
|
|
57
|
+
if (args[i + 1] && !args[i + 1].startsWith('-')) {
|
|
58
|
+
options.package = args[++i];
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
case '--version':
|
|
62
|
+
case '-v':
|
|
63
|
+
if (args[i + 1]) {
|
|
64
|
+
options.version = args[++i];
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
case '--folder':
|
|
68
|
+
case '-f':
|
|
69
|
+
if (args[i + 1]) {
|
|
70
|
+
options.folder = args[++i];
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
case '--verbose':
|
|
74
|
+
case '-V':
|
|
75
|
+
options.verbose = true;
|
|
76
|
+
break;
|
|
77
|
+
case 'add':
|
|
78
|
+
if (args[i + 1]) {
|
|
79
|
+
options.subcommand = 'add';
|
|
80
|
+
options.package = args[++i];
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case 'remove':
|
|
84
|
+
case 'rm':
|
|
85
|
+
if (args[i + 1]) {
|
|
86
|
+
options.subcommand = 'remove';
|
|
87
|
+
options.package = args[++i];
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
case 'list':
|
|
91
|
+
options.subcommand = 'list';
|
|
92
|
+
break;
|
|
93
|
+
case 'help':
|
|
94
|
+
case '--help':
|
|
95
|
+
case '-h':
|
|
96
|
+
printHelp();
|
|
97
|
+
process.exit(0);
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
if (!arg.startsWith('-') && !options.package) {
|
|
101
|
+
options.package = arg;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
i++;
|
|
105
|
+
}
|
|
106
|
+
return options;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Run pre-install scan
|
|
110
|
+
*/
|
|
111
|
+
async function runPreInstall(options) {
|
|
112
|
+
if (!options.package) {
|
|
113
|
+
console.error('Error: Package name required');
|
|
114
|
+
console.error('Usage: npm-scan pre install <package> [--version <version>');
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
console.log(`\n🔍 Scanning package: ${options.package}${options.version ? '@' + options.version : ''}\n`);
|
|
118
|
+
const scanner = (0, scanner_1.createScanner)({ checkVulnerabilities: true });
|
|
119
|
+
const result = await scanner.preInstallScan(options.package, options.version);
|
|
120
|
+
printScanResult(result, options.verbose);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Run post-install scan
|
|
124
|
+
*/
|
|
125
|
+
async function runPostInstall(options) {
|
|
126
|
+
console.log(`\n🔍 Scanning installed packages...\n`);
|
|
127
|
+
const scanner = (0, scanner_1.createScanner)({ checkVulnerabilities: true });
|
|
128
|
+
const result = await scanner.postInstallScan(options.folder);
|
|
129
|
+
printPostScanResult(result);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Run full scan (pre + post)
|
|
133
|
+
*/
|
|
134
|
+
async function runFullScan(options) {
|
|
135
|
+
if (!options.package) {
|
|
136
|
+
console.error('Error: Package name required');
|
|
137
|
+
console.error('Usage: npm-scan scan <package> [--version <version>]');
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
console.log(`\n🔍 Full scan of: ${options.package}${options.version ? '@' + options.version : ''}\n`);
|
|
141
|
+
const scanner = (0, scanner_1.createScanner)({ checkVulnerabilities: true });
|
|
142
|
+
const pre = await scanner.preInstallScan(options.package, options.version);
|
|
143
|
+
printScanResult(pre, options.verbose);
|
|
144
|
+
if (pre.status !== 'blocked') {
|
|
145
|
+
const post = await scanner.postInstallScan(options.folder);
|
|
146
|
+
printPostScanResult(post);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Blocklist management
|
|
151
|
+
*/
|
|
152
|
+
async function runBlocklist(options) {
|
|
153
|
+
switch (options.subcommand) {
|
|
154
|
+
case 'add':
|
|
155
|
+
if (!options.package) {
|
|
156
|
+
console.error('Error: Package name required');
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
blocklist_1.blocklistManager.addToBlocklist(options.package, 'Manually added by user');
|
|
160
|
+
console.log(`✅ Added ${options.package} to blocklist`);
|
|
161
|
+
break;
|
|
162
|
+
case 'remove':
|
|
163
|
+
if (!options.package) {
|
|
164
|
+
console.error('Error: Package name required');
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
const removed = blocklist_1.blocklistManager.removeFromBlocklist(options.package);
|
|
168
|
+
if (removed) {
|
|
169
|
+
console.log(`✅ Removed ${options.package} from blocklist`);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
console.log(`ℹ️ ${options.package} was not in blocklist`);
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
case 'list':
|
|
176
|
+
default:
|
|
177
|
+
const list = blocklist_1.blocklistManager.getBlocklist();
|
|
178
|
+
console.log(`\n📋 Blocklisted packages (${list.length}):\n`);
|
|
179
|
+
for (const entry of list.slice(0, 50)) {
|
|
180
|
+
console.log(` • ${entry.package} [${entry.severity}]`);
|
|
181
|
+
console.log(` ${entry.reason}`);
|
|
182
|
+
}
|
|
183
|
+
if (list.length > 50) {
|
|
184
|
+
console.log(` ... and ${list.length - 50} more`);
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Print pre-install scan result
|
|
191
|
+
*/
|
|
192
|
+
function printScanResult(result, verbose = false) {
|
|
193
|
+
const statusEmoji = {
|
|
194
|
+
safe: '✅',
|
|
195
|
+
warning: '⚠️',
|
|
196
|
+
danger: '🚨',
|
|
197
|
+
blocked: '🛑'
|
|
198
|
+
}[result.status];
|
|
199
|
+
console.log(`${statusEmoji} ${result.packageName}@${result.version} - ${result.status.toUpperCase()}`);
|
|
200
|
+
console.log(` Score: ${result.score}/100`);
|
|
201
|
+
console.log('');
|
|
202
|
+
if (result.threats.length > 0) {
|
|
203
|
+
console.log('📌 Threats detected:');
|
|
204
|
+
for (const threat of result.threats) {
|
|
205
|
+
const severityIcon = {
|
|
206
|
+
low: '🔵',
|
|
207
|
+
medium: '🟡',
|
|
208
|
+
high: '🟠',
|
|
209
|
+
critical: '🔴'
|
|
210
|
+
}[threat.severity];
|
|
211
|
+
console.log(` ${severityIcon} [${threat.severity.toUpperCase()}] ${threat.type}: ${threat.message}`);
|
|
212
|
+
if (threat.details && verbose) {
|
|
213
|
+
console.log(` ${threat.details}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
console.log(' No threats detected');
|
|
219
|
+
}
|
|
220
|
+
console.log('');
|
|
221
|
+
// Print metadata if verbose
|
|
222
|
+
if (verbose && result.metadata) {
|
|
223
|
+
const meta = result.metadata;
|
|
224
|
+
console.log('📦 Package info:');
|
|
225
|
+
if (meta.description)
|
|
226
|
+
console.log(` ${meta.description}`);
|
|
227
|
+
if (meta.publisher)
|
|
228
|
+
console.log(` Publisher: ${meta.publisher.username}`);
|
|
229
|
+
if (meta.license)
|
|
230
|
+
console.log(` License: ${meta.license}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Print post-install scan result
|
|
235
|
+
*/
|
|
236
|
+
function printPostScanResult(result) {
|
|
237
|
+
console.log(`📊 Scanned ${result.scannedPackages} packages in ${result.duration}ms`);
|
|
238
|
+
console.log('');
|
|
239
|
+
if (result.threats.length > 0) {
|
|
240
|
+
console.log(`🚨 Found ${result.threats.length} threats:\n`);
|
|
241
|
+
const bySeverity = {
|
|
242
|
+
critical: [],
|
|
243
|
+
high: [],
|
|
244
|
+
medium: [],
|
|
245
|
+
low: []
|
|
246
|
+
};
|
|
247
|
+
for (const threat of result.threats) {
|
|
248
|
+
bySeverity[threat.severity].push(threat);
|
|
249
|
+
}
|
|
250
|
+
for (const severity of ['critical', 'high', 'medium', 'low']) {
|
|
251
|
+
const threats = bySeverity[severity];
|
|
252
|
+
if (threats.length > 0) {
|
|
253
|
+
console.log(` ${severity.toUpperCase()} (${threats.length}):`);
|
|
254
|
+
for (const threat of threats.slice(0, 10)) {
|
|
255
|
+
console.log(` ${threat.package}/${threat.file}`);
|
|
256
|
+
console.log(` ${threat.message}`);
|
|
257
|
+
}
|
|
258
|
+
if (threats.length > 10) {
|
|
259
|
+
console.log(` ... and ${threats.length - 10} more`);
|
|
260
|
+
}
|
|
261
|
+
console.log('');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
console.log('✅ No threats detected');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Print help
|
|
271
|
+
*/
|
|
272
|
+
function printHelp() {
|
|
273
|
+
console.log(`
|
|
274
|
+
npm-scan 🔒 Security scanner for npm packages
|
|
275
|
+
|
|
276
|
+
Usage:
|
|
277
|
+
npm-scan pre install <package> [--version <version>] Pre-install security scan
|
|
278
|
+
npm-scan post [--folder <path>] Post-install scan
|
|
279
|
+
npm-scan scan <package> [--version <version>] Full scan (pre + post)
|
|
280
|
+
npm-scan blocklist add <package> Add to blocklist
|
|
281
|
+
npm-scan blocklist remove <package> Remove from blocklist
|
|
282
|
+
npm-scan blocklist list List blocked packages
|
|
283
|
+
npm-scan help This help message
|
|
284
|
+
|
|
285
|
+
Options:
|
|
286
|
+
-v, --version <version> Package version to scan
|
|
287
|
+
-f, --folder <path> node_modules folder path
|
|
288
|
+
-V, --verbose Verbose output
|
|
289
|
+
-h, --help Show this help
|
|
290
|
+
|
|
291
|
+
Examples:
|
|
292
|
+
npm-scan pre install lodash
|
|
293
|
+
npm-scan pre install axios --version 1.6.0
|
|
294
|
+
npm-scan post
|
|
295
|
+
npm-scan blocklist list
|
|
296
|
+
`);
|
|
297
|
+
}
|
|
298
|
+
exports.default = { run };
|
|
299
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocklist management
|
|
3
|
+
* Maintains list of known malicious packages
|
|
4
|
+
*/
|
|
5
|
+
import type { BlocklistEntry } from '../types';
|
|
6
|
+
declare const TYPOSQUATTING_PATTERNS: {
|
|
7
|
+
pattern: string;
|
|
8
|
+
variations: string[];
|
|
9
|
+
}[];
|
|
10
|
+
export declare class BlocklistManager {
|
|
11
|
+
private userBlocklist;
|
|
12
|
+
private blocklistPath;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Check if a package is blocklisted
|
|
16
|
+
*/
|
|
17
|
+
isBlocklisted(packageName: string): BlocklistEntry | null;
|
|
18
|
+
/**
|
|
19
|
+
* Check for typosquatting
|
|
20
|
+
*/
|
|
21
|
+
detectTyposquatting(packageName: string): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Add package to user blocklist
|
|
24
|
+
*/
|
|
25
|
+
addToBlocklist(packageName: string, reason: string, severity?: 'high' | 'critical'): void;
|
|
26
|
+
/**
|
|
27
|
+
* Remove package from user blocklist
|
|
28
|
+
*/
|
|
29
|
+
removeFromBlocklist(packageName: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Get all blocklisted packages
|
|
32
|
+
*/
|
|
33
|
+
getBlocklist(): BlocklistEntry[];
|
|
34
|
+
/**
|
|
35
|
+
* Load user blocklist from disk
|
|
36
|
+
*/
|
|
37
|
+
private loadUserBlocklist;
|
|
38
|
+
/**
|
|
39
|
+
* Save user blocklist to disk
|
|
40
|
+
*/
|
|
41
|
+
private saveUserBlocklist;
|
|
42
|
+
}
|
|
43
|
+
export declare const blocklistManager: BlocklistManager;
|
|
44
|
+
export { TYPOSQUATTING_PATTERNS };
|
|
45
|
+
//# sourceMappingURL=blocklist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocklist.d.ts","sourceRoot":"","sources":["../../src/lib/blocklist.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAgF/C,QAAA,MAAM,sBAAsB;;;GA2B3B,CAAC;AAEF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,aAAa,CAAS;;IAO9B;;OAEG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAmBzD;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE;IAalD;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,GAAG,UAAmB,GAAG,IAAI;IAYjG;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAQjD;;OAEG;IACH,YAAY,IAAI,cAAc,EAAE;IAchC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAQ1B;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Blocklist management
|
|
4
|
+
* Maintains list of known malicious packages
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.TYPOSQUATTING_PATTERNS = exports.blocklistManager = exports.BlocklistManager = void 0;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
// Known malicious packages (community-sourced & well-documented attacks)
|
|
45
|
+
const KNOWN_MALICIOUS = {
|
|
46
|
+
// Famous supply chain attacks
|
|
47
|
+
'event-stream': {
|
|
48
|
+
package: 'event-stream',
|
|
49
|
+
reason: 'flatmap-stream malicious code injection (Dec 2018) - copay窃取加密货币',
|
|
50
|
+
severity: 'critical',
|
|
51
|
+
source: 'npm security incident'
|
|
52
|
+
},
|
|
53
|
+
'flatmap-stream': {
|
|
54
|
+
package: 'flatmap-stream',
|
|
55
|
+
reason: 'Malicious dependency of event-stream that stole cryptocurrency wallet keys',
|
|
56
|
+
severity: 'critical',
|
|
57
|
+
source: 'npm security incident'
|
|
58
|
+
},
|
|
59
|
+
'popcorn-native': {
|
|
60
|
+
package: 'popcorn-native',
|
|
61
|
+
reason: 'Malicious package that exfiltrated environment variables',
|
|
62
|
+
severity: 'critical',
|
|
63
|
+
source: 'npm advisory'
|
|
64
|
+
},
|
|
65
|
+
'ngx-rocket': {
|
|
66
|
+
package: 'ngx-rocket',
|
|
67
|
+
reason: 'Contains malicious postinstall script that crypto mine',
|
|
68
|
+
severity: 'critical',
|
|
69
|
+
source: 'npm advisory'
|
|
70
|
+
},
|
|
71
|
+
'ruddy': {
|
|
72
|
+
package: 'ruddy',
|
|
73
|
+
reason: '_typosquatting of rudder - steals credentials',
|
|
74
|
+
severity: 'critical',
|
|
75
|
+
source: 'npm advisory'
|
|
76
|
+
},
|
|
77
|
+
'rudder': {
|
|
78
|
+
package: 'rudder',
|
|
79
|
+
reason: 'Typosquatting of rudder - steals credentials',
|
|
80
|
+
severity: 'critical',
|
|
81
|
+
source: 'npm advisory'
|
|
82
|
+
},
|
|
83
|
+
'jquery-mobile': {
|
|
84
|
+
package: 'jquery-mobile',
|
|
85
|
+
reason: 'Malicious version with backdoor',
|
|
86
|
+
severity: 'critical',
|
|
87
|
+
source: 'npm advisory'
|
|
88
|
+
},
|
|
89
|
+
'vue-tetris': {
|
|
90
|
+
package: 'vue-tetris',
|
|
91
|
+
reason: 'Malicious package - sends user data to remote server',
|
|
92
|
+
severity: 'critical',
|
|
93
|
+
source: 'npm advisory'
|
|
94
|
+
},
|
|
95
|
+
'react-scripts': {
|
|
96
|
+
package: 'react-scripts',
|
|
97
|
+
reason: 'Malicious version that created reverse shell',
|
|
98
|
+
severity: 'critical',
|
|
99
|
+
source: 'npm advisory'
|
|
100
|
+
},
|
|
101
|
+
'ariatosys-logger': {
|
|
102
|
+
package: 'ariatosys-logger',
|
|
103
|
+
reason: 'logger typosquat with malicious code',
|
|
104
|
+
severity: 'critical',
|
|
105
|
+
source: 'npm community'
|
|
106
|
+
},
|
|
107
|
+
'syslog': {
|
|
108
|
+
package: 'syslog',
|
|
109
|
+
reason: 'Malicious version - installs rootkit',
|
|
110
|
+
severity: 'critical',
|
|
111
|
+
source: 'npm community'
|
|
112
|
+
},
|
|
113
|
+
'buffertools': {
|
|
114
|
+
package: 'buffertools',
|
|
115
|
+
reason: 'Malicious version with native code that executes arbitrary commands',
|
|
116
|
+
severity: 'critical',
|
|
117
|
+
source: 'npm advisory'
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
// Common typosquatting patterns to detect
|
|
121
|
+
const TYPOSQUATTING_PATTERNS = [
|
|
122
|
+
// Popular packages often typosquatted
|
|
123
|
+
{ pattern: 'lodash', variations: ['lodsh', 'lodas', 'lodah', 'lodih', 'loadsh'] },
|
|
124
|
+
{ pattern: 'axios', variations: ['axio', 'axois', 'azios', 'axuox'] },
|
|
125
|
+
{ pattern: 'express', variations: ['expres', 'exprss', 'expresz', 'exprress'] },
|
|
126
|
+
{ pattern: 'react', variations: ['reactt', 'reacet', 'reacgt', 'reacvt'] },
|
|
127
|
+
{ pattern: 'vue', variations: ['vu', 'vve', 'vuer', 'fvue'] },
|
|
128
|
+
{ pattern: 'moment', variations: ['momemt', 'momnet', 'momnt', 'momemtn'] },
|
|
129
|
+
{ pattern: 'lodash', variations: ['lodsh', 'lodas', 'lodah', 'lodih', 'loadsh'] },
|
|
130
|
+
{ pattern: 'mongoose', variations: ['mongeose', 'mognoose', 'mangos'] },
|
|
131
|
+
{ pattern: 'webpack', variations: ['webback', 'webpak', 'webpac'] },
|
|
132
|
+
{ pattern: 'eslint', variations: ['easylint', 'eslint', 'esline'] },
|
|
133
|
+
{ pattern: 'nodemon', variations: ['nodomen', 'nodmon', 'nodon'] },
|
|
134
|
+
{ pattern: 'pm2', variations: ['pm', 'p2m', 'pn2'] },
|
|
135
|
+
{ pattern: 'typescript', variations: ['typesript', 'type-script', 'tsc'] },
|
|
136
|
+
{ pattern: 'dotenv', variations: ['doten', 'dotenV', 'dotenvn'] },
|
|
137
|
+
{ pattern: 'async', variations: ['asycn', 'asyc', 'assync'] },
|
|
138
|
+
{ pattern: 'qs', variations: ['qss', 's', 'q'] },
|
|
139
|
+
{ pattern: 'minimist', variations: ['minimist', 'minimist-', 'minimist_'] },
|
|
140
|
+
{ pattern: 'extend', variations: ['exten', 'extnd', 'extend_'] },
|
|
141
|
+
{ pattern: 'request', variations: ['requst', 'reqest', 'rqequest'] },
|
|
142
|
+
{ pattern: 'chalk', variations: ['chalck', 'chalk-', 'halck'] },
|
|
143
|
+
{ pattern: 'commander', variations: ['comman', 'commender', 'commnad'] },
|
|
144
|
+
{ pattern: 'inquirer', variations: ['inquir', 'inquer', 'enquire'] },
|
|
145
|
+
{ pattern: 'bluebird', variations: ['bluebir', 'bluebd', 'bloodbird'] },
|
|
146
|
+
{ pattern: 'underscore', variations: ['undrscore', 'underscro', '_score'] },
|
|
147
|
+
{ pattern: 'lodash-es', variations: ['lodashes', 'lodash_es', 'loadsh-es'] }
|
|
148
|
+
];
|
|
149
|
+
exports.TYPOSQUATTING_PATTERNS = TYPOSQUATTING_PATTERNS;
|
|
150
|
+
class BlocklistManager {
|
|
151
|
+
userBlocklist = new Map();
|
|
152
|
+
blocklistPath;
|
|
153
|
+
constructor() {
|
|
154
|
+
this.blocklistPath = path.join(os.homedir(), '.npm-scan-blocklist.json');
|
|
155
|
+
this.loadUserBlocklist();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if a package is blocklisted
|
|
159
|
+
*/
|
|
160
|
+
isBlocklisted(packageName) {
|
|
161
|
+
const lowerName = packageName.toLowerCase();
|
|
162
|
+
// Check known malicious
|
|
163
|
+
if (KNOWN_MALICIOUS[lowerName]) {
|
|
164
|
+
return {
|
|
165
|
+
...KNOWN_MALICIOUS[lowerName],
|
|
166
|
+
addedAt: '2018-12-01'
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// Check user blocklist
|
|
170
|
+
if (this.userBlocklist.has(lowerName)) {
|
|
171
|
+
return this.userBlocklist.get(lowerName);
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Check for typosquatting
|
|
177
|
+
*/
|
|
178
|
+
detectTyposquatting(packageName) {
|
|
179
|
+
const lowerName = packageName.toLowerCase();
|
|
180
|
+
const matches = [];
|
|
181
|
+
for (const { pattern, variations } of TYPOSQUATTING_PATTERNS) {
|
|
182
|
+
if (variations.includes(lowerName)) {
|
|
183
|
+
matches.push(pattern);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return matches;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Add package to user blocklist
|
|
190
|
+
*/
|
|
191
|
+
addToBlocklist(packageName, reason, severity = 'high') {
|
|
192
|
+
const entry = {
|
|
193
|
+
package: packageName.toLowerCase(),
|
|
194
|
+
reason,
|
|
195
|
+
addedAt: new Date().toISOString(),
|
|
196
|
+
severity
|
|
197
|
+
};
|
|
198
|
+
this.userBlocklist.set(packageName.toLowerCase(), entry);
|
|
199
|
+
this.saveUserBlocklist();
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Remove package from user blocklist
|
|
203
|
+
*/
|
|
204
|
+
removeFromBlocklist(packageName) {
|
|
205
|
+
const removed = this.userBlocklist.delete(packageName.toLowerCase());
|
|
206
|
+
if (removed) {
|
|
207
|
+
this.saveUserBlocklist();
|
|
208
|
+
}
|
|
209
|
+
return removed;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get all blocklisted packages
|
|
213
|
+
*/
|
|
214
|
+
getBlocklist() {
|
|
215
|
+
const entries = [];
|
|
216
|
+
for (const entry of Object.values(KNOWN_MALICIOUS)) {
|
|
217
|
+
entries.push({ ...entry, addedAt: '2018-12-01' });
|
|
218
|
+
}
|
|
219
|
+
for (const entry of this.userBlocklist.values()) {
|
|
220
|
+
entries.push(entry);
|
|
221
|
+
}
|
|
222
|
+
return entries;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Load user blocklist from disk
|
|
226
|
+
*/
|
|
227
|
+
loadUserBlocklist() {
|
|
228
|
+
try {
|
|
229
|
+
if (fs.existsSync(this.blocklistPath)) {
|
|
230
|
+
const data = fs.readFileSync(this.blocklistPath, 'utf-8');
|
|
231
|
+
const entries = JSON.parse(data);
|
|
232
|
+
for (const entry of entries) {
|
|
233
|
+
this.userBlocklist.set(entry.package, entry);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
// Ignore errors
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Save user blocklist to disk
|
|
243
|
+
*/
|
|
244
|
+
saveUserBlocklist() {
|
|
245
|
+
try {
|
|
246
|
+
const entries = Array.from(this.userBlocklist.values());
|
|
247
|
+
fs.writeFileSync(this.blocklistPath, JSON.stringify(entries, null, 2));
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
throw new Error(`Failed to save blocklist: ${e}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.BlocklistManager = BlocklistManager;
|
|
255
|
+
exports.blocklistManager = new BlocklistManager();
|
|
256
|
+
//# sourceMappingURL=blocklist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocklist.js","sourceRoot":"","sources":["../../src/lib/blocklist.ts"],"names":[],"mappings":"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"}
|