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.
Files changed (56) hide show
  1. package/.eslintrc.json +32 -0
  2. package/.github/CODEOWNERS +3 -0
  3. package/.github/workflows/ci.yml +105 -0
  4. package/.prettierrc +10 -0
  5. package/FUNDING.yml +1 -0
  6. package/PLAN.md +151 -0
  7. package/README.md +150 -0
  8. package/bin/npm-scan +13 -0
  9. package/bin/npm-scan-wrap +100 -0
  10. package/dist/cli/index.d.ts +18 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +299 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/lib/blocklist.d.ts +45 -0
  15. package/dist/lib/blocklist.d.ts.map +1 -0
  16. package/dist/lib/blocklist.js +256 -0
  17. package/dist/lib/blocklist.js.map +1 -0
  18. package/dist/lib/extended.js +314 -0
  19. package/dist/lib/extended.js.map +1 -0
  20. package/dist/lib/integrity.js +247 -0
  21. package/dist/lib/integrity.js.map +1 -0
  22. package/dist/lib/patterns.d.ts +76 -0
  23. package/dist/lib/patterns.d.ts.map +1 -0
  24. package/dist/lib/patterns.js +414 -0
  25. package/dist/lib/patterns.js.map +1 -0
  26. package/dist/lib/registry.d.ts +42 -0
  27. package/dist/lib/registry.d.ts.map +1 -0
  28. package/dist/lib/registry.js +157 -0
  29. package/dist/lib/registry.js.map +1 -0
  30. package/dist/lib/scanner.d.ts +43 -0
  31. package/dist/lib/scanner.d.ts.map +1 -0
  32. package/dist/lib/scanner.js +432 -0
  33. package/dist/lib/scanner.js.map +1 -0
  34. package/dist/lib/vuln.js +284 -0
  35. package/dist/lib/vuln.js.map +1 -0
  36. package/dist/types.d.ts +85 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +6 -0
  39. package/dist/types.js.map +1 -0
  40. package/jest.config.js +18 -0
  41. package/package.json +56 -0
  42. package/src/cli/index.ts +336 -0
  43. package/src/lib/blocklist.ts +239 -0
  44. package/src/lib/extended.ts +384 -0
  45. package/src/lib/integrity.ts +253 -0
  46. package/src/lib/patterns.ts +404 -0
  47. package/src/lib/registry.ts +146 -0
  48. package/src/lib/scanner.ts +447 -0
  49. package/src/lib/vuln.ts +321 -0
  50. package/src/types.ts +102 -0
  51. package/tests/blocklist.test.ts +89 -0
  52. package/tests/extended.test.ts +204 -0
  53. package/tests/patterns.test.ts +147 -0
  54. package/tests/scanner.test.ts +116 -0
  55. package/tests/vuln.test.ts +66 -0
  56. package/tsconfig.json +20 -0
@@ -0,0 +1,414 @@
1
+ "use strict";
2
+ /**
3
+ * Detection patterns for malicious code, obfuscation, and suspicious behavior
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.CODE_EXTENSIONS = exports.SENSITIVE_FILES = exports.SUSPICIOUS_SCRIPTS = exports.SUSPICIOUS_PATTERNS = exports.OBFUSCATION_PATTERNS = void 0;
40
+ exports.scanFile = scanFile;
41
+ exports.scanPackageJsonScripts = scanPackageJsonScripts;
42
+ exports.scanDirectory = scanDirectory;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ // Patterns that indicate obfuscated code
46
+ const OBFUSCATION_PATTERNS = [
47
+ {
48
+ pattern: /eval\s*\(\s*(?:atob|fromCharCode|String\.fromCharCode)/gi,
49
+ type: 'obfuscation',
50
+ severity: 'high',
51
+ message: 'eval() with character code decoding - common obfuscation technique'
52
+ },
53
+ {
54
+ pattern: /eval\s*\(\s*["'`]([A-Za-z0-9+\/=]{100,})["'`]*/gi,
55
+ type: 'obfuscation',
56
+ severity: 'high',
57
+ message: 'eval() with base64-encoded string'
58
+ },
59
+ {
60
+ pattern: /new\s+Function\s*\(\s*(?:atob|fromCharCode)/gi,
61
+ type: 'obfuscation',
62
+ severity: 'high',
63
+ message: 'Dynamic Function with character code decoding'
64
+ },
65
+ {
66
+ pattern: /\\x([0-9a-fA-F]{2})/g,
67
+ type: 'obfuscation',
68
+ severity: 'medium',
69
+ message: 'Hex-encoded characters in code'
70
+ },
71
+ {
72
+ pattern: /\\u([0-9a-fA-F]{4})/g,
73
+ type: 'obfuscation',
74
+ severity: 'medium',
75
+ message: 'Unicode-escaped characters in code'
76
+ },
77
+ {
78
+ pattern: /(?:atob|btoa)\s*\([^)]*\)/g,
79
+ type: 'obfuscation',
80
+ severity: 'medium',
81
+ message: 'Base64 encoding/decoding functions detected'
82
+ },
83
+ {
84
+ pattern: /String\.fromCharCode\((?:\s*\d+\s*,?)+\)/g,
85
+ type: 'obfuscation',
86
+ severity: 'medium',
87
+ message: 'String.fromCharCode() to hide code'
88
+ },
89
+ {
90
+ pattern: /\$_\s*=\s*["'`]/g,
91
+ type: 'obfuscation',
92
+ severity: 'low',
93
+ message: 'Unusual variable naming pattern'
94
+ }
95
+ ];
96
+ exports.OBFUSCATION_PATTERNS = OBFUSCATION_PATTERNS;
97
+ // Patterns that indicate malicious/malware behavior
98
+ const SUSPICIOUS_PATTERNS = [
99
+ {
100
+ pattern: /(?:process\.env|process)\s*\.\s*(?:env|argv)\s*\[.*?(?:KEY|SECRET|TOKEN|PASS|Auth|Credential)/gi,
101
+ type: 'suspicious_code',
102
+ severity: 'critical',
103
+ message: 'Accessing environment variables with sensitive keywords'
104
+ },
105
+ {
106
+ pattern: /fetch\s*\(\s*["'](?:https?:)?\/\/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/gi,
107
+ type: 'suspicious_code',
108
+ severity: 'high',
109
+ message: 'Network request to IP address (bypasses DNS)'
110
+ },
111
+ {
112
+ pattern: /https?:\/\/(?:pastebin|hastebin|ipfs\.io|cloudflare|workers\.dev)\.\w+/gi,
113
+ type: 'suspicious_code',
114
+ severity: 'high',
115
+ message: 'Network request to external code hosting service'
116
+ },
117
+ {
118
+ pattern: /child_process\s*\.\s*(?:exec|spawn|sync)\s*\(\s*["'`]/gi,
119
+ type: 'suspicious_code',
120
+ severity: 'high',
121
+ message: 'Executing shell commands from package code'
122
+ },
123
+ {
124
+ pattern: /net\.connect\(|require\s*\(\s*["'](?:net|http|tls|crypto)["']\s*\)/gi,
125
+ type: 'suspicious_code',
126
+ severity: 'medium',
127
+ message: 'Network or crypto module required'
128
+ },
129
+ {
130
+ pattern: /require\s*\(\s*["'](?:child_process|exec|spawn)["']\s*\)/gi,
131
+ type: 'suspicious_code',
132
+ severity: 'high',
133
+ message: 'child_process module required - potential command execution'
134
+ },
135
+ {
136
+ pattern: /setTimeout\s*\(\s*["'`]/gi,
137
+ type: 'suspicious_code',
138
+ severity: 'low',
139
+ message: 'Delayed code execution'
140
+ },
141
+ {
142
+ pattern: /setInterval\s*\(\s*["'`]/gi,
143
+ type: 'suspicious_code',
144
+ severity: 'low',
145
+ message: 'Repeating scheduled code execution'
146
+ },
147
+ {
148
+ pattern: /\.exec\s*\(|child_process\.\s*exec/gi,
149
+ type: 'suspicious_code',
150
+ severity: 'high',
151
+ message: 'Shell command execution'
152
+ },
153
+ {
154
+ pattern: /fs\s*\.\s*(?:readFile|writeFile|appendFile|readFileSync|writeFileSync)\s*\(\s*(?:__dirname|process\.cwd\(\))/gi,
155
+ type: 'suspicious_code',
156
+ severity: 'medium',
157
+ message: 'File system access in package root'
158
+ },
159
+ {
160
+ pattern: /(?:readdirSync|readdir|readFileSync|readlinkSync)\s*\(\s*(?:\.|process\.cwd)/gi,
161
+ type: 'suspicious_code',
162
+ severity: 'medium',
163
+ message: 'Scanning directories outside package'
164
+ },
165
+ {
166
+ pattern: /eval\s*\(\s*process\.env/gi,
167
+ type: 'suspicious_code',
168
+ severity: 'critical',
169
+ message: 'Evaluating environment variables'
170
+ },
171
+ {
172
+ pattern: /require\s*\(\s*["'](?:https?|http)["']\s*\)/gi,
173
+ type: 'suspicious_code',
174
+ severity: 'medium',
175
+ message: 'HTTP/HTTPS module required'
176
+ },
177
+ {
178
+ pattern: /crypto\s*\.\s*createHash\s*\(\s*["'](?:sha|md5)["']\s*\)/gi,
179
+ type: 'suspicious_code',
180
+ severity: 'low',
181
+ message: 'Cryptographic hashing'
182
+ },
183
+ {
184
+ // Crypto mining patterns
185
+ pattern: /(?:stratum\+tcp|stratum\.bitcoin|cgminer|antminer|cryptonight)/gi,
186
+ type: 'suspicious_code',
187
+ severity: 'critical',
188
+ message: 'Crypto mining pool connection detected'
189
+ },
190
+ {
191
+ // Keylogging patterns
192
+ pattern: /(?:addEventListener\s*\(\s*["'](?:keydown|keypress|keyup)|onkey)/gi,
193
+ type: 'suspicious_code',
194
+ severity: 'high',
195
+ message: 'Keyboard event listener - potential keylogger'
196
+ },
197
+ {
198
+ pattern: /(?:key|code)\s*:\s*(?:\d{1,3}\s*,?\s*){3,}/gi,
199
+ type: 'suspicious_code',
200
+ severity: 'high',
201
+ message: 'Potential keyboard scanning code'
202
+ }
203
+ ];
204
+ exports.SUSPICIOUS_PATTERNS = SUSPICIOUS_PATTERNS;
205
+ // Suspicious lifecycle scripts in package.json
206
+ const SUSPICIOUS_SCRIPTS = [
207
+ {
208
+ script: 'postinstall',
209
+ severity: 'high',
210
+ message: 'postinstall script executes automatically after install'
211
+ },
212
+ {
213
+ script: 'preinstall',
214
+ severity: 'medium',
215
+ message: 'preinstall script runs before package installs'
216
+ },
217
+ {
218
+ script: 'postpublish',
219
+ severity: 'medium',
220
+ message: 'postpublish script runs after package is published'
221
+ },
222
+ {
223
+ script: 'preuninstall',
224
+ severity: 'low',
225
+ message: 'preuninstall script runs before uninstall'
226
+ },
227
+ {
228
+ script: 'postuninstall',
229
+ severity: 'medium',
230
+ message: 'postuninstall script runs after uninstall'
231
+ },
232
+ {
233
+ script: 'preversion',
234
+ severity: 'low',
235
+ message: 'preversion script runs before version bump'
236
+ },
237
+ {
238
+ script: 'postversion',
239
+ severity: 'low',
240
+ message: 'postversion script runs after version bump'
241
+ },
242
+ {
243
+ script: 'prepack',
244
+ severity: 'low',
245
+ message: 'prepack script runs before packing'
246
+ },
247
+ {
248
+ script: 'postpack',
249
+ severity: 'low',
250
+ message: 'postpack script runs after packing'
251
+ },
252
+ {
253
+ script: 'prepare',
254
+ severity: 'low',
255
+ message: 'prepare script runs on install and publish'
256
+ }
257
+ ];
258
+ exports.SUSPICIOUS_SCRIPTS = SUSPICIOUS_SCRIPTS;
259
+ // Sensitive files that should not be in packages
260
+ const SENSITIVE_FILES = [
261
+ /\.env$/,
262
+ /\.env\.[a-z]+$/,
263
+ /\.git\/config$/,
264
+ /\.aws\/credentials$/,
265
+ /\.ssh\/id_.*$/,
266
+ /credentials\.json$/,
267
+ /\.npmrc$/,
268
+ /\.htpasswd$/,
269
+ /secrets\.ya?ml$/,
270
+ /\.pem$/,
271
+ /\.key$/,
272
+ /\.p12$/,
273
+ /\.pfx$/,
274
+ /id_rsa/,
275
+ /id_dsa/,
276
+ /\.bash_history$/,
277
+ /\.zsh_history$/,
278
+ /\.history$/,
279
+ /_history$/,
280
+ /\.sql$/,
281
+ /\.db$/
282
+ ];
283
+ exports.SENSITIVE_FILES = SENSITIVE_FILES;
284
+ // File extensions that might contain executable code
285
+ const CODE_EXTENSIONS = [
286
+ '.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx',
287
+ '.py', '.rb', '.php', '.pl', '.sh', '.bash',
288
+ '.exe', '.dll', '.so', '.dylib', '.bin',
289
+ '.wasm', '.class', '.jar'
290
+ ];
291
+ exports.CODE_EXTENSIONS = CODE_EXTENSIONS;
292
+ /**
293
+ * Scan a single file for suspicious patterns
294
+ */
295
+ function scanFile(filePath, content) {
296
+ const threats = [];
297
+ const fileName = path.basename(filePath);
298
+ const ext = path.extname(filePath).toLowerCase();
299
+ // Skip node_modules packages themselves
300
+ if (filePath.includes('node_modules/')) {
301
+ return [];
302
+ }
303
+ // Check for obfuscation patterns
304
+ for (const { pattern, type, severity, message } of OBFUSCATION_PATTERNS) {
305
+ const matches = content.match(pattern);
306
+ if (matches) {
307
+ threats.push({
308
+ package: 'scanning',
309
+ file: fileName,
310
+ type,
311
+ severity,
312
+ message,
313
+ code: matches[0].substring(0, 100)
314
+ });
315
+ }
316
+ }
317
+ // Check for suspicious patterns (only in code files)
318
+ if (CODE_EXTENSIONS.includes(ext)) {
319
+ for (const { pattern, type, severity, message } of SUSPICIOUS_PATTERNS) {
320
+ const matches = content.match(pattern);
321
+ if (matches) {
322
+ threats.push({
323
+ package: 'scanning',
324
+ file: fileName,
325
+ type,
326
+ severity,
327
+ message,
328
+ code: matches[0].substring(0, 100)
329
+ });
330
+ }
331
+ }
332
+ }
333
+ // Check for sensitive files
334
+ for (const pattern of SENSITIVE_FILES) {
335
+ if (pattern.test(fileName)) {
336
+ threats.push({
337
+ package: 'scanning',
338
+ file: fileName,
339
+ type: 'suspicious_code',
340
+ severity: 'high',
341
+ message: `Sensitive file detected in package: ${fileName}`
342
+ });
343
+ }
344
+ }
345
+ return threats;
346
+ }
347
+ /**
348
+ * Check package.json scripts for suspicious behavior
349
+ */
350
+ function scanPackageJsonScripts(scripts) {
351
+ const threats = [];
352
+ if (!scripts)
353
+ return threats;
354
+ for (const [scriptName, scriptContent] of Object.entries(scripts)) {
355
+ const scriptDef = SUSPICIOUS_SCRIPTS.find(s => s.script === scriptName);
356
+ if (scriptDef) {
357
+ // Check if script content is suspicious
358
+ const isSuspicious = /curl|wget|npm|node|yarn|python|perl|bash|sh|\||&&|\$\(|;/.test(scriptContent) ||
359
+ scriptContent.length > 200;
360
+ threats.push({
361
+ package: 'scanning',
362
+ file: 'package.json',
363
+ type: isSuspicious ? 'suspicious_script' : 'supply_chain',
364
+ severity: isSuspicious ? scriptDef.severity : 'low',
365
+ message: `${scriptDef.message}: "${scriptName}"`,
366
+ code: scriptContent.substring(0, 100)
367
+ });
368
+ }
369
+ }
370
+ return threats;
371
+ }
372
+ /**
373
+ * Scan directory for all files
374
+ */
375
+ function scanDirectory(dirPath, extensions) {
376
+ const files = new Map();
377
+ const codeExtensions = extensions || CODE_EXTENSIONS;
378
+ function walkDir(dir, basePath = '') {
379
+ try {
380
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
381
+ for (const entry of entries) {
382
+ const fullPath = path.join(dir, entry.name);
383
+ const relativePath = path.join(basePath, entry.name);
384
+ if (entry.isDirectory()) {
385
+ // Skip certain directories
386
+ if (['node_modules', '.git', 'test', '__tests__', 'coverage'].includes(entry.name)) {
387
+ continue;
388
+ }
389
+ walkDir(fullPath, relativePath);
390
+ }
391
+ else if (entry.isFile()) {
392
+ const ext = path.extname(entry.name).toLowerCase();
393
+ if (codeExtensions.includes(ext)) {
394
+ try {
395
+ const content = fs.readFileSync(fullPath, 'utf-8');
396
+ if (content.length < 1_000_000) { // Skip files > 1MB
397
+ files.set(relativePath, content);
398
+ }
399
+ }
400
+ catch (e) {
401
+ // Skip binary or unreadable files
402
+ }
403
+ }
404
+ }
405
+ }
406
+ }
407
+ catch (e) {
408
+ // Skip inaccessible directories
409
+ }
410
+ }
411
+ walkDir(dirPath);
412
+ return files;
413
+ }
414
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/lib/patterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * npm registry API client
3
+ * Fetches package metadata and tarballs from npm registry
4
+ */
5
+ import type { PackageMetadata, ScanOptions } from './types';
6
+ export declare class RegistryClient {
7
+ private registry;
8
+ private cache;
9
+ constructor(options?: {
10
+ registry?: string;
11
+ });
12
+ /**
13
+ * Fetch package metadata from npm registry
14
+ */
15
+ getPackageMetadata(packageName: string, version?: string): Promise<PackageMetadata>;
16
+ /**
17
+ * Normalize npm registry response to our PackageMetadata type
18
+ */
19
+ private normalizeMetadata;
20
+ /**
21
+ * Download and extract package tarball to temp directory
22
+ */
23
+ downloadPackage(packageName: string, version?: string): Promise<{
24
+ tempDir: string;
25
+ files: string[];
26
+ integrity: string;
27
+ }>;
28
+ /**
29
+ * Recursively get all files in directory
30
+ */
31
+ private getAllFiles;
32
+ /**
33
+ * Clean up temp directory
34
+ */
35
+ cleanup(tempDir: string): void;
36
+ /**
37
+ * Get all available versions of a package
38
+ */
39
+ getVersions(packageName: string): Promise<string[]>;
40
+ }
41
+ export declare function createRegistryClient(options?: ScanOptions): RegistryClient;
42
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/lib/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI5D,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAA2C;gBAE5C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAI3C;;OAEG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA6BzF;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;OAEG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QACpE,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IA2CF;;OAEG;IACH,OAAO,CAAC,WAAW;IAoBnB;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ9B;;OAEG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAS1D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,cAAc,CAE1E"}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * npm registry API client
4
+ * Fetches package metadata and tarballs from npm registry using native fetch
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.RegistryClient = void 0;
41
+ exports.createRegistryClient = createRegistryClient;
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const os = __importStar(require("os"));
45
+ const tar = __importStar(require("tar"));
46
+ const crypto = __importStar(require("crypto"));
47
+ const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
48
+ class RegistryClient {
49
+ registry;
50
+ cache = new Map();
51
+ constructor(options) {
52
+ this.registry = options?.registry || DEFAULT_REGISTRY;
53
+ }
54
+ /**
55
+ * Fetch package metadata from npm registry
56
+ */
57
+ async getPackageMetadata(packageName, version) {
58
+ const cacheKey = `${packageName}@${version || 'latest'}`;
59
+ if (this.cache.has(cacheKey)) {
60
+ return this.cache.get(cacheKey);
61
+ }
62
+ const url = `${this.registry}/${packageName}${version ? `/${version}` : ''}`;
63
+ try {
64
+ const response = await fetch(url);
65
+ if (!response.ok) {
66
+ if (response.status === 404) {
67
+ throw new Error(`Package not found: ${packageName}`);
68
+ }
69
+ throw new Error(`Failed to fetch ${packageName}: ${response.statusText}`);
70
+ }
71
+ const data = await response.json();
72
+ this.cache.set(cacheKey, data);
73
+ return data;
74
+ }
75
+ catch (error) {
76
+ throw new Error(`Failed to fetch ${packageName}: ${error.message}`);
77
+ }
78
+ }
79
+ /**
80
+ * Download and extract package tarball to temp directory
81
+ */
82
+ async downloadPackage(packageName, version) {
83
+ const metadata = await this.getPackageMetadata(packageName, version);
84
+ const dist = metadata.dist || {};
85
+ if (!dist.tarball) {
86
+ throw new Error(`No tarball found for ${packageName}`);
87
+ }
88
+ const tempDir = path.join(os.tmpdir(), `npm-scan-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);
89
+ fs.mkdirSync(tempDir, { recursive: true });
90
+ const tarballPath = path.join(tempDir, 'package.tgz');
91
+ // Download tarball
92
+ const response = await fetch(dist.tarball);
93
+ const arrayBuffer = await response.arrayBuffer();
94
+ const buffer = Buffer.from(arrayBuffer);
95
+ fs.writeFileSync(tarballPath, buffer);
96
+ // Calculate integrity hash (sha512)
97
+ const integrity = 'sha512-' + crypto.createHash('sha512').update(buffer).digest('base64');
98
+ // Extract tarball
99
+ const extractDir = path.join(tempDir, 'package');
100
+ fs.mkdirSync(extractDir, { recursive: true });
101
+ await tar.extract({
102
+ file: tarballPath,
103
+ cwd: extractDir
104
+ });
105
+ // Get list of extracted files
106
+ const files = this.getAllFiles(extractDir);
107
+ return { tempDir, files, integrity };
108
+ }
109
+ /**
110
+ * Recursively get all files in directory
111
+ */
112
+ getAllFiles(dir, baseDir) {
113
+ const files = [];
114
+ const base = baseDir || dir;
115
+ try {
116
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
117
+ for (const entry of entries) {
118
+ const fullPath = path.join(dir, entry.name);
119
+ const relativePath = path.relative(base, fullPath);
120
+ if (entry.isDirectory()) {
121
+ files.push(...this.getAllFiles(fullPath, base));
122
+ }
123
+ else if (entry.isFile()) {
124
+ files.push(relativePath);
125
+ }
126
+ }
127
+ }
128
+ catch (e) {
129
+ // Skip inaccessible
130
+ }
131
+ return files;
132
+ }
133
+ /**
134
+ * Clean up temp directory
135
+ */
136
+ cleanup(tempDir) {
137
+ try {
138
+ fs.rmSync(tempDir, { recursive: true, force: true });
139
+ }
140
+ catch (e) {
141
+ // Ignore cleanup errors
142
+ }
143
+ }
144
+ /**
145
+ * Get all available versions of a package
146
+ */
147
+ async getVersions(packageName) {
148
+ const response = await fetch(`${this.registry}/${packageName}`);
149
+ const data = await response.json();
150
+ return Object.keys(data.versions || {}).sort();
151
+ }
152
+ }
153
+ exports.RegistryClient = RegistryClient;
154
+ function createRegistryClient(options) {
155
+ return new RegistryClient({ registry: options?.registry });
156
+ }
157
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/lib/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Core scanner module
3
+ * Pre and post-install security scanning for npm packages
4
+ */
5
+ import type { ScanResult, ScanOptions, PostInstallScanResult } from '../types';
6
+ /**
7
+ * Main scanner class
8
+ */
9
+ export declare class Scanner {
10
+ private registry;
11
+ private options;
12
+ constructor(options?: ScanOptions);
13
+ /**
14
+ * Pre-install scan: Check a package before installation
15
+ */
16
+ preInstallScan(packageName: string, version?: string): Promise<ScanResult>;
17
+ /**
18
+ * Post-install scan: Scan downloaded packages
19
+ */
20
+ postInstallScan(folderPath?: string): Promise<PostInstallScanResult>;
21
+ /**
22
+ * Full scan: Pre-scan, then install, then post-scan
23
+ */
24
+ fullScan(packageName: string, version?: string, folderPath?: string): Promise<{
25
+ pre: ScanResult;
26
+ post: PostInstallScanResult;
27
+ }>;
28
+ /**
29
+ * Find all packages in node_modules
30
+ */
31
+ private findPackages;
32
+ /**
33
+ * Determine overall status from threats and score
34
+ */
35
+ private determineStatus;
36
+ }
37
+ export declare function createScanner(options?: ScanOptions): Scanner;
38
+ declare const _default: {
39
+ Scanner: typeof Scanner;
40
+ createScanner: typeof createScanner;
41
+ };
42
+ export default _default;
43
+ //# sourceMappingURL=scanner.d.ts.map