mitnick-cli 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 +21 -0
- package/README.md +193 -0
- package/dist/analyzers/analyzer.interface.d.ts +32 -0
- package/dist/analyzers/analyzer.interface.d.ts.map +1 -0
- package/dist/analyzers/analyzer.interface.js +2 -0
- package/dist/analyzers/analyzer.interface.js.map +1 -0
- package/dist/analyzers/analyzer.registry.d.ts +16 -0
- package/dist/analyzers/analyzer.registry.d.ts.map +1 -0
- package/dist/analyzers/analyzer.registry.js +40 -0
- package/dist/analyzers/analyzer.registry.js.map +1 -0
- package/dist/analyzers/dependency-confusion/index.d.ts +14 -0
- package/dist/analyzers/dependency-confusion/index.d.ts.map +1 -0
- package/dist/analyzers/dependency-confusion/index.js +147 -0
- package/dist/analyzers/dependency-confusion/index.js.map +1 -0
- package/dist/analyzers/dormant-package/index.d.ts +14 -0
- package/dist/analyzers/dormant-package/index.d.ts.map +1 -0
- package/dist/analyzers/dormant-package/index.js +137 -0
- package/dist/analyzers/dormant-package/index.js.map +1 -0
- package/dist/analyzers/file-based-analyzer.d.ts +20 -0
- package/dist/analyzers/file-based-analyzer.d.ts.map +1 -0
- package/dist/analyzers/file-based-analyzer.js +35 -0
- package/dist/analyzers/file-based-analyzer.js.map +1 -0
- package/dist/analyzers/install-scripts/index.d.ts +13 -0
- package/dist/analyzers/install-scripts/index.d.ts.map +1 -0
- package/dist/analyzers/install-scripts/index.js +125 -0
- package/dist/analyzers/install-scripts/index.js.map +1 -0
- package/dist/analyzers/license/index.d.ts +12 -0
- package/dist/analyzers/license/index.d.ts.map +1 -0
- package/dist/analyzers/license/index.js +199 -0
- package/dist/analyzers/license/index.js.map +1 -0
- package/dist/analyzers/maintainer/index.d.ts +12 -0
- package/dist/analyzers/maintainer/index.d.ts.map +1 -0
- package/dist/analyzers/maintainer/index.js +93 -0
- package/dist/analyzers/maintainer/index.js.map +1 -0
- package/dist/analyzers/network-calls/index.d.ts +15 -0
- package/dist/analyzers/network-calls/index.d.ts.map +1 -0
- package/dist/analyzers/network-calls/index.js +212 -0
- package/dist/analyzers/network-calls/index.js.map +1 -0
- package/dist/analyzers/obfuscation/index.d.ts +19 -0
- package/dist/analyzers/obfuscation/index.d.ts.map +1 -0
- package/dist/analyzers/obfuscation/index.js +218 -0
- package/dist/analyzers/obfuscation/index.js.map +1 -0
- package/dist/analyzers/prototype-pollution/index.d.ts +18 -0
- package/dist/analyzers/prototype-pollution/index.d.ts.map +1 -0
- package/dist/analyzers/prototype-pollution/index.js +257 -0
- package/dist/analyzers/prototype-pollution/index.js.map +1 -0
- package/dist/analyzers/sensitive-data/index.d.ts +16 -0
- package/dist/analyzers/sensitive-data/index.d.ts.map +1 -0
- package/dist/analyzers/sensitive-data/index.js +254 -0
- package/dist/analyzers/sensitive-data/index.js.map +1 -0
- package/dist/analyzers/typosquatting/index.d.ts +14 -0
- package/dist/analyzers/typosquatting/index.d.ts.map +1 -0
- package/dist/analyzers/typosquatting/index.js +127 -0
- package/dist/analyzers/typosquatting/index.js.map +1 -0
- package/dist/analyzers/typosquatting/popular-packages.d.ts +9 -0
- package/dist/analyzers/typosquatting/popular-packages.d.ts.map +1 -0
- package/dist/analyzers/typosquatting/popular-packages.js +236 -0
- package/dist/analyzers/typosquatting/popular-packages.js.map +1 -0
- package/dist/analyzers/vulnerability/index.d.ts +12 -0
- package/dist/analyzers/vulnerability/index.d.ts.map +1 -0
- package/dist/analyzers/vulnerability/index.js +147 -0
- package/dist/analyzers/vulnerability/index.js.map +1 -0
- package/dist/cli/commands/check.d.ts +21 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +204 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/formatters/formatter.interface.d.ts +14 -0
- package/dist/cli/formatters/formatter.interface.d.ts.map +1 -0
- package/dist/cli/formatters/formatter.interface.js +2 -0
- package/dist/cli/formatters/formatter.interface.js.map +1 -0
- package/dist/cli/formatters/json.d.ts +12 -0
- package/dist/cli/formatters/json.d.ts.map +1 -0
- package/dist/cli/formatters/json.js +12 -0
- package/dist/cli/formatters/json.js.map +1 -0
- package/dist/cli/formatters/sarif.d.ts +13 -0
- package/dist/cli/formatters/sarif.d.ts.map +1 -0
- package/dist/cli/formatters/sarif.js +101 -0
- package/dist/cli/formatters/sarif.js.map +1 -0
- package/dist/cli/formatters/terminal.d.ts +13 -0
- package/dist/cli/formatters/terminal.d.ts.map +1 -0
- package/dist/cli/formatters/terminal.js +110 -0
- package/dist/cli/formatters/terminal.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +86 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/engine.d.ts +23 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +55 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/scorer.d.ts +30 -0
- package/dist/core/scorer.d.ts.map +1 -0
- package/dist/core/scorer.js +88 -0
- package/dist/core/scorer.js.map +1 -0
- package/dist/core/types.d.ts +76 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +30 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/registry/client.d.ts +27 -0
- package/dist/registry/client.d.ts.map +1 -0
- package/dist/registry/client.js +189 -0
- package/dist/registry/client.js.map +1 -0
- package/dist/registry/tarball.d.ts +34 -0
- package/dist/registry/tarball.d.ts.map +1 -0
- package/dist/registry/tarball.js +103 -0
- package/dist/registry/tarball.js.map +1 -0
- package/dist/utils/ast.d.ts +74 -0
- package/dist/utils/ast.d.ts.map +1 -0
- package/dist/utils/ast.js +150 -0
- package/dist/utils/ast.js.map +1 -0
- package/dist/utils/fs.d.ts +28 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +78 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/http.d.ts +40 -0
- package/dist/utils/http.d.ts.map +1 -0
- package/dist/utils/http.js +116 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/logger.d.ts +46 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +91 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/strings.d.ts +8 -0
- package/dist/utils/strings.d.ts.map +1 -0
- package/dist/utils/strings.js +12 -0
- package/dist/utils/strings.js.map +1 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/dormant-package/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for analyzers that walk source files in the extracted package.
|
|
3
|
+
*
|
|
4
|
+
* Subclasses only need to implement `analyzeFile()` — the file-walking boilerplate
|
|
5
|
+
* (directory traversal, extension filtering, safe reads) is handled here.
|
|
6
|
+
*/
|
|
7
|
+
import type { Analyzer } from './analyzer.interface.js';
|
|
8
|
+
import type { AnalysisContext, AnalyzerResult, Finding } from '../core/types.js';
|
|
9
|
+
export declare abstract class FileBasedAnalyzer implements Analyzer {
|
|
10
|
+
abstract readonly name: string;
|
|
11
|
+
abstract readonly description: string;
|
|
12
|
+
/**
|
|
13
|
+
* Analyze a single source file and return any findings.
|
|
14
|
+
* @param source The file contents as a UTF-8 string.
|
|
15
|
+
* @param relativePath The path relative to the extraction root.
|
|
16
|
+
*/
|
|
17
|
+
protected abstract analyzeFile(source: string, relativePath: string): Finding[];
|
|
18
|
+
analyze(context: AnalysisContext): Promise<AnalyzerResult>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=file-based-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-based-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/file-based-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAKjF,8BAAsB,iBAAkB,YAAW,QAAQ;IACzD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAEtC;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,EAAE;IAEzE,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CA0BjE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for analyzers that walk source files in the extracted package.
|
|
3
|
+
*
|
|
4
|
+
* Subclasses only need to implement `analyzeFile()` — the file-walking boilerplate
|
|
5
|
+
* (directory traversal, extension filtering, safe reads) is handled here.
|
|
6
|
+
*/
|
|
7
|
+
import { walkDirectory, readFileSafe, isAnalyzableFile } from '../utils/fs.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
import { relative } from 'node:path';
|
|
10
|
+
export class FileBasedAnalyzer {
|
|
11
|
+
async analyze(context) {
|
|
12
|
+
const start = performance.now();
|
|
13
|
+
const findings = [];
|
|
14
|
+
try {
|
|
15
|
+
for await (const filePath of walkDirectory(context.extractedPath)) {
|
|
16
|
+
if (!isAnalyzableFile(filePath))
|
|
17
|
+
continue;
|
|
18
|
+
const source = await readFileSafe(filePath);
|
|
19
|
+
if (source === null || source.length === 0)
|
|
20
|
+
continue;
|
|
21
|
+
const relPath = relative(context.extractedPath, filePath);
|
|
22
|
+
findings.push(...this.analyzeFile(source, relPath));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
logger.warn(`[${this.name}] Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
analyzer: this.name,
|
|
30
|
+
findings,
|
|
31
|
+
duration: performance.now() - start,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=file-based-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-based-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/file-based-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,OAAgB,iBAAiB;IAWrC,KAAK,CAAC,OAAO,CAAC,OAAwB;QACpC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,IAAI,CAAC;YACH,IAAI,KAAK,EAAE,MAAM,QAAQ,IAAI,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;gBAClE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBAE1C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAS;gBAErD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;gBAC1D,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CACT,IAAI,IAAI,CAAC,IAAI,uBAAuB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAC;QACJ,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,QAAQ;YACR,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;SACpC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install Script Analyzer — detects lifecycle scripts in package.json
|
|
3
|
+
* and analyzes their contents for suspicious patterns.
|
|
4
|
+
*/
|
|
5
|
+
import type { Analyzer } from '../analyzer.interface.js';
|
|
6
|
+
import type { AnalysisContext, AnalyzerResult } from '../../core/types.js';
|
|
7
|
+
export declare class InstallScriptAnalyzer implements Analyzer {
|
|
8
|
+
readonly name = "install-scripts";
|
|
9
|
+
readonly description = "Detects lifecycle scripts and analyzes their contents for suspicious patterns";
|
|
10
|
+
analyze(context: AnalysisContext): Promise<AnalyzerResult>;
|
|
11
|
+
private detectSuspiciousPatterns;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/install-scripts/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAqB,MAAM,qBAAqB,CAAC;AA2E9F,qBAAa,qBAAsB,YAAW,QAAQ;IACpD,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,WAAW,mFAC8D;IAElF,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAiD1D,OAAO,CAAC,wBAAwB;CAkBjC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install Script Analyzer — detects lifecycle scripts in package.json
|
|
3
|
+
* and analyzes their contents for suspicious patterns.
|
|
4
|
+
*/
|
|
5
|
+
import { truncate } from '../../utils/strings.js';
|
|
6
|
+
import { logger } from '../../utils/logger.js';
|
|
7
|
+
// ─── Constants ────────────────────────────────────────────
|
|
8
|
+
const LIFECYCLE_HOOKS = [
|
|
9
|
+
'preinstall',
|
|
10
|
+
'install',
|
|
11
|
+
'postinstall',
|
|
12
|
+
'preuninstall',
|
|
13
|
+
'postuninstall',
|
|
14
|
+
];
|
|
15
|
+
const SUSPICIOUS_PATTERNS = [
|
|
16
|
+
{ pattern: /\bcurl\b/i, label: 'curl command (network download)', severity: 'critical' },
|
|
17
|
+
{ pattern: /\bwget\b/i, label: 'wget command (network download)', severity: 'critical' },
|
|
18
|
+
{ pattern: /\beval\b/, label: 'eval usage (dynamic code execution)', severity: 'critical' },
|
|
19
|
+
{
|
|
20
|
+
pattern: /\bnew\s+Function\b/,
|
|
21
|
+
label: 'new Function() (dynamic code creation)',
|
|
22
|
+
severity: 'critical',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
pattern: /\b(base64|atob|btoa|Buffer\.from)\b/,
|
|
26
|
+
label: 'encoded string handling',
|
|
27
|
+
severity: 'critical',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
pattern: /\b(sh|bash|cmd|powershell|pwsh)\s+-c\b/,
|
|
31
|
+
label: 'shell spawning',
|
|
32
|
+
severity: 'critical',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
pattern: /\bchild_process\b/,
|
|
36
|
+
label: 'child_process usage (subprocess spawning)',
|
|
37
|
+
severity: 'critical',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
pattern: /\b(exec|execSync|spawn|spawnSync|execFile)\b/,
|
|
41
|
+
label: 'process execution',
|
|
42
|
+
severity: 'critical',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
pattern: /process\.env/,
|
|
46
|
+
label: 'environment variable access',
|
|
47
|
+
severity: 'high',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
pattern: /\$\{?\w*HOME\b|\$\{?\w*USER\b|\$\{?\w*PATH\b/,
|
|
51
|
+
label: 'environment variable reference',
|
|
52
|
+
severity: 'high',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
pattern: /https?:\/\/[^\s"']+/,
|
|
56
|
+
label: 'hardcoded URL',
|
|
57
|
+
severity: 'high',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
pattern: /\brm\s+-rf\b/,
|
|
61
|
+
label: 'recursive file deletion',
|
|
62
|
+
severity: 'high',
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
// ─── Analyzer ─────────────────────────────────────────────
|
|
66
|
+
export class InstallScriptAnalyzer {
|
|
67
|
+
name = 'install-scripts';
|
|
68
|
+
description = 'Detects lifecycle scripts and analyzes their contents for suspicious patterns';
|
|
69
|
+
analyze(context) {
|
|
70
|
+
const start = performance.now();
|
|
71
|
+
const findings = [];
|
|
72
|
+
try {
|
|
73
|
+
const scripts = context.packageJson['scripts'];
|
|
74
|
+
if (scripts === null || scripts === undefined || typeof scripts !== 'object') {
|
|
75
|
+
return Promise.resolve({
|
|
76
|
+
analyzer: this.name,
|
|
77
|
+
findings: [],
|
|
78
|
+
duration: performance.now() - start,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
const scriptsRecord = scripts;
|
|
82
|
+
for (const hook of LIFECYCLE_HOOKS) {
|
|
83
|
+
const scriptValue = scriptsRecord[hook];
|
|
84
|
+
if (typeof scriptValue !== 'string')
|
|
85
|
+
continue;
|
|
86
|
+
const scriptContent = scriptValue;
|
|
87
|
+
// Flag presence of any lifecycle hook
|
|
88
|
+
findings.push({
|
|
89
|
+
analyzer: this.name,
|
|
90
|
+
severity: 'high',
|
|
91
|
+
title: `Lifecycle script detected: ${hook}`,
|
|
92
|
+
description: `The package defines a "${hook}" script: "${truncate(scriptContent, 120)}"`,
|
|
93
|
+
recommendation: 'Review the script carefully before installing. Consider using --ignore-scripts flag.',
|
|
94
|
+
});
|
|
95
|
+
// Analyze content for suspicious patterns
|
|
96
|
+
const suspiciousMatches = this.detectSuspiciousPatterns(scriptContent, hook);
|
|
97
|
+
findings.push(...suspiciousMatches);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
logger.warn(`[${this.name}] Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
102
|
+
}
|
|
103
|
+
return Promise.resolve({
|
|
104
|
+
analyzer: this.name,
|
|
105
|
+
findings,
|
|
106
|
+
duration: performance.now() - start,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
detectSuspiciousPatterns(script, hook) {
|
|
110
|
+
const findings = [];
|
|
111
|
+
for (const { pattern, label, severity } of SUSPICIOUS_PATTERNS) {
|
|
112
|
+
if (pattern.test(script)) {
|
|
113
|
+
findings.push({
|
|
114
|
+
analyzer: this.name,
|
|
115
|
+
severity: severity === 'critical' ? 'critical' : 'high',
|
|
116
|
+
title: `Suspicious content in ${hook}: ${label}`,
|
|
117
|
+
description: `The "${hook}" script contains ${label}. Script: "${truncate(script, 200)}"`,
|
|
118
|
+
recommendation: 'Inspect the script manually. This pattern is commonly seen in malicious packages.',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return findings;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/install-scripts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License Analyzer — checks the package's license field for compliance
|
|
3
|
+
* risks including copyleft, missing, and non-standard licenses.
|
|
4
|
+
*/
|
|
5
|
+
import type { Analyzer } from '../analyzer.interface.js';
|
|
6
|
+
import type { AnalysisContext, AnalyzerResult } from '../../core/types.js';
|
|
7
|
+
export declare class LicenseAnalyzer implements Analyzer {
|
|
8
|
+
readonly name = "license";
|
|
9
|
+
readonly description = "Checks package license for compliance risks and missing license information";
|
|
10
|
+
analyze(context: AnalysisContext): Promise<AnalyzerResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/license/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAqB,MAAM,qBAAqB,CAAC;AA6F9F,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,WAAW,iFAC4D;IAEhF,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAiI3D"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License Analyzer — checks the package's license field for compliance
|
|
3
|
+
* risks including copyleft, missing, and non-standard licenses.
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from '../../utils/logger.js';
|
|
6
|
+
// ─── License classifications ─────────────────────────────
|
|
7
|
+
/** Permissive licenses that are generally safe for any use. */
|
|
8
|
+
const PERMISSIVE_LICENSES = [
|
|
9
|
+
'MIT',
|
|
10
|
+
'Apache-2.0',
|
|
11
|
+
'BSD-2-Clause',
|
|
12
|
+
'BSD-3-Clause',
|
|
13
|
+
'ISC',
|
|
14
|
+
'Unlicense',
|
|
15
|
+
'CC0-1.0',
|
|
16
|
+
'0BSD',
|
|
17
|
+
'Artistic-2.0',
|
|
18
|
+
'Zlib',
|
|
19
|
+
'BSL-1.0',
|
|
20
|
+
'PostgreSQL',
|
|
21
|
+
'BlueOak-1.0.0',
|
|
22
|
+
];
|
|
23
|
+
/** Copyleft licenses that impose distribution requirements. */
|
|
24
|
+
const COPYLEFT_LICENSES = [
|
|
25
|
+
'GPL-2.0',
|
|
26
|
+
'GPL-2.0-only',
|
|
27
|
+
'GPL-2.0-or-later',
|
|
28
|
+
'GPL-3.0',
|
|
29
|
+
'GPL-3.0-only',
|
|
30
|
+
'GPL-3.0-or-later',
|
|
31
|
+
'AGPL-3.0',
|
|
32
|
+
'AGPL-3.0-only',
|
|
33
|
+
'AGPL-3.0-or-later',
|
|
34
|
+
'LGPL-2.0',
|
|
35
|
+
'LGPL-2.0-only',
|
|
36
|
+
'LGPL-2.0-or-later',
|
|
37
|
+
'LGPL-2.1',
|
|
38
|
+
'LGPL-2.1-only',
|
|
39
|
+
'LGPL-2.1-or-later',
|
|
40
|
+
'LGPL-3.0',
|
|
41
|
+
'LGPL-3.0-only',
|
|
42
|
+
'LGPL-3.0-or-later',
|
|
43
|
+
'MPL-2.0',
|
|
44
|
+
'EUPL-1.1',
|
|
45
|
+
'EUPL-1.2',
|
|
46
|
+
'SSPL-1.0',
|
|
47
|
+
'CPAL-1.0',
|
|
48
|
+
'OSL-3.0',
|
|
49
|
+
'CECILL-2.1',
|
|
50
|
+
];
|
|
51
|
+
// ─── Helpers ──────────────────────────────────────────────
|
|
52
|
+
function normalizeIdentifier(license) {
|
|
53
|
+
return license.trim().replace(/\s+/g, '-');
|
|
54
|
+
}
|
|
55
|
+
function isPermissive(identifier) {
|
|
56
|
+
const upper = identifier.toUpperCase();
|
|
57
|
+
return PERMISSIVE_LICENSES.some((l) => l.toUpperCase() === upper);
|
|
58
|
+
}
|
|
59
|
+
function isCopyleft(identifier) {
|
|
60
|
+
const upper = identifier.toUpperCase();
|
|
61
|
+
return COPYLEFT_LICENSES.some((l) => l.toUpperCase() === upper);
|
|
62
|
+
}
|
|
63
|
+
function isCopyleftPrefix(identifier) {
|
|
64
|
+
const upper = identifier.toUpperCase();
|
|
65
|
+
return (upper.startsWith('GPL') ||
|
|
66
|
+
upper.startsWith('AGPL') ||
|
|
67
|
+
upper.startsWith('LGPL') ||
|
|
68
|
+
upper.startsWith('MPL') ||
|
|
69
|
+
upper.startsWith('EUPL') ||
|
|
70
|
+
upper.startsWith('SSPL') ||
|
|
71
|
+
upper.startsWith('CPAL'));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse a simple SPDX expression (handles OR and AND but not complex nesting).
|
|
75
|
+
* Returns individual identifiers.
|
|
76
|
+
*/
|
|
77
|
+
function parseSpdxIdentifiers(expression) {
|
|
78
|
+
return expression
|
|
79
|
+
.split(/\s+(?:OR|AND|WITH)\s+/i)
|
|
80
|
+
.map((s) => s.replace(/[()]/g, '').trim())
|
|
81
|
+
.filter((s) => s.length > 0);
|
|
82
|
+
}
|
|
83
|
+
// ─── Analyzer ─────────────────────────────────────────────
|
|
84
|
+
export class LicenseAnalyzer {
|
|
85
|
+
name = 'license';
|
|
86
|
+
description = 'Checks package license for compliance risks and missing license information';
|
|
87
|
+
analyze(context) {
|
|
88
|
+
const start = performance.now();
|
|
89
|
+
const findings = [];
|
|
90
|
+
try {
|
|
91
|
+
const licenseField = context.packageJson['license'];
|
|
92
|
+
// Check for missing license
|
|
93
|
+
if (licenseField === undefined || licenseField === null) {
|
|
94
|
+
findings.push({
|
|
95
|
+
analyzer: this.name,
|
|
96
|
+
severity: 'medium',
|
|
97
|
+
title: 'Missing license',
|
|
98
|
+
description: 'The package does not declare a license in package.json. ' +
|
|
99
|
+
'Without a license, default copyright laws apply and you may not have permission to use the code.',
|
|
100
|
+
recommendation: 'Contact the maintainer to clarify the licensing terms.',
|
|
101
|
+
});
|
|
102
|
+
return Promise.resolve({
|
|
103
|
+
analyzer: this.name,
|
|
104
|
+
findings,
|
|
105
|
+
duration: performance.now() - start,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// Handle legacy "licenses" array format
|
|
109
|
+
if (typeof licenseField !== 'string') {
|
|
110
|
+
findings.push({
|
|
111
|
+
analyzer: this.name,
|
|
112
|
+
severity: 'low',
|
|
113
|
+
title: 'Non-standard license format',
|
|
114
|
+
description: 'The license field is not a string. It may use a legacy format or be improperly defined.',
|
|
115
|
+
recommendation: 'Review the package license manually.',
|
|
116
|
+
});
|
|
117
|
+
return Promise.resolve({
|
|
118
|
+
analyzer: this.name,
|
|
119
|
+
findings,
|
|
120
|
+
duration: performance.now() - start,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const licenseString = licenseField;
|
|
124
|
+
// Check for common "no license" patterns
|
|
125
|
+
if (licenseString === 'UNLICENSED' ||
|
|
126
|
+
licenseString === 'SEE LICENSE IN LICENSE' ||
|
|
127
|
+
licenseString.toUpperCase() === 'NONE') {
|
|
128
|
+
const severity = licenseString === 'UNLICENSED' ? 'medium' : 'low';
|
|
129
|
+
findings.push({
|
|
130
|
+
analyzer: this.name,
|
|
131
|
+
severity,
|
|
132
|
+
title: licenseString === 'UNLICENSED'
|
|
133
|
+
? 'Proprietary/unlicensed package'
|
|
134
|
+
: 'Custom license reference',
|
|
135
|
+
description: `The package license is "${licenseString}". ` +
|
|
136
|
+
(licenseString === 'UNLICENSED'
|
|
137
|
+
? 'This means it is proprietary and you may not have permission to use it.'
|
|
138
|
+
: 'Review the referenced license file for terms.'),
|
|
139
|
+
recommendation: 'Review the license terms before using this package.',
|
|
140
|
+
});
|
|
141
|
+
return Promise.resolve({
|
|
142
|
+
analyzer: this.name,
|
|
143
|
+
findings,
|
|
144
|
+
duration: performance.now() - start,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
// Parse SPDX identifiers
|
|
148
|
+
const identifiers = parseSpdxIdentifiers(licenseString);
|
|
149
|
+
let hasCopyleft = false;
|
|
150
|
+
let hasPermissive = false;
|
|
151
|
+
let hasUnknown = false;
|
|
152
|
+
for (const identifier of identifiers) {
|
|
153
|
+
const normalized = normalizeIdentifier(identifier);
|
|
154
|
+
if (isPermissive(normalized)) {
|
|
155
|
+
hasPermissive = true;
|
|
156
|
+
}
|
|
157
|
+
else if (isCopyleft(normalized) || isCopyleftPrefix(normalized)) {
|
|
158
|
+
hasCopyleft = true;
|
|
159
|
+
findings.push({
|
|
160
|
+
analyzer: this.name,
|
|
161
|
+
severity: 'medium',
|
|
162
|
+
title: `Copyleft license: ${normalized}`,
|
|
163
|
+
description: `The package uses the ${normalized} license, which requires derivative works ` +
|
|
164
|
+
'to be distributed under the same license terms.',
|
|
165
|
+
recommendation: 'Ensure your project complies with copyleft requirements, or choose an alternative package.',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
hasUnknown = true;
|
|
170
|
+
findings.push({
|
|
171
|
+
analyzer: this.name,
|
|
172
|
+
severity: 'low',
|
|
173
|
+
title: `Non-standard license: ${normalized}`,
|
|
174
|
+
description: `The license identifier "${normalized}" is not a commonly recognized SPDX identifier.`,
|
|
175
|
+
recommendation: 'Review the license terms manually to understand your obligations.',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Info finding for permissive-only licenses
|
|
180
|
+
if (hasPermissive && !hasCopyleft && !hasUnknown) {
|
|
181
|
+
findings.push({
|
|
182
|
+
analyzer: this.name,
|
|
183
|
+
severity: 'info',
|
|
184
|
+
title: `Permissive license: ${licenseString}`,
|
|
185
|
+
description: `The package uses the permissive ${licenseString} license.`,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
logger.warn(`[${this.name}] Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
191
|
+
}
|
|
192
|
+
return Promise.resolve({
|
|
193
|
+
analyzer: this.name,
|
|
194
|
+
findings,
|
|
195
|
+
duration: performance.now() - start,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/license/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maintainer Analyzer — evaluates package maintainer health using
|
|
3
|
+
* registry metadata (bus factor, maintainer count).
|
|
4
|
+
*/
|
|
5
|
+
import type { Analyzer } from '../analyzer.interface.js';
|
|
6
|
+
import type { AnalysisContext, AnalyzerResult } from '../../core/types.js';
|
|
7
|
+
export declare class MaintainerAnalyzer implements Analyzer {
|
|
8
|
+
readonly name = "maintainer";
|
|
9
|
+
readonly description = "Evaluates package maintainer health and bus factor risk";
|
|
10
|
+
analyze(context: AnalysisContext): Promise<AnalyzerResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/maintainer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAW,MAAM,qBAAqB,CAAC;AAKpF,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,6DAA6D;IAEjF,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CA4F3D"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maintainer Analyzer — evaluates package maintainer health using
|
|
3
|
+
* registry metadata (bus factor, maintainer count).
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from '../../utils/logger.js';
|
|
6
|
+
// ─── Analyzer ─────────────────────────────────────────────
|
|
7
|
+
export class MaintainerAnalyzer {
|
|
8
|
+
name = 'maintainer';
|
|
9
|
+
description = 'Evaluates package maintainer health and bus factor risk';
|
|
10
|
+
analyze(context) {
|
|
11
|
+
const start = performance.now();
|
|
12
|
+
const findings = [];
|
|
13
|
+
try {
|
|
14
|
+
const { maintainers } = context.registryMetadata;
|
|
15
|
+
if (maintainers.length === 0) {
|
|
16
|
+
findings.push({
|
|
17
|
+
analyzer: this.name,
|
|
18
|
+
severity: 'medium',
|
|
19
|
+
title: 'No maintainers listed',
|
|
20
|
+
description: 'The package has no maintainers listed in the registry metadata. ' +
|
|
21
|
+
'This could indicate an abandoned or improperly published package.',
|
|
22
|
+
recommendation: 'Verify the package is actively maintained before relying on it.',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else if (maintainers.length === 1) {
|
|
26
|
+
const maintainer = maintainers[0];
|
|
27
|
+
findings.push({
|
|
28
|
+
analyzer: this.name,
|
|
29
|
+
severity: 'low',
|
|
30
|
+
title: 'Single maintainer (bus factor = 1)',
|
|
31
|
+
description: `The package has only one maintainer: ${maintainer?.name ?? 'unknown'}. ` +
|
|
32
|
+
'If this person becomes unavailable, the package may become unmaintained.',
|
|
33
|
+
recommendation: 'Consider the risk of depending on a single-maintainer package. ' +
|
|
34
|
+
'Check if there are alternative packages with broader maintainer support.',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
findings.push({
|
|
39
|
+
analyzer: this.name,
|
|
40
|
+
severity: 'info',
|
|
41
|
+
title: `${maintainers.length} maintainers`,
|
|
42
|
+
description: `The package has ${maintainers.length} maintainers: ` +
|
|
43
|
+
`${maintainers.map((m) => m.name).join(', ')}.`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Check if the package was recently published (new package risk)
|
|
47
|
+
const publishedAt = context.registryMetadata.publishedAt;
|
|
48
|
+
if (publishedAt !== undefined && publishedAt !== '') {
|
|
49
|
+
const publishDate = new Date(publishedAt);
|
|
50
|
+
const now = new Date();
|
|
51
|
+
const ageInDays = (now.getTime() - publishDate.getTime()) / (1000 * 60 * 60 * 24);
|
|
52
|
+
if (ageInDays < 7) {
|
|
53
|
+
findings.push({
|
|
54
|
+
analyzer: this.name,
|
|
55
|
+
severity: 'medium',
|
|
56
|
+
title: 'Very recently published version',
|
|
57
|
+
description: `This version was published ${Math.floor(ageInDays)} day(s) ago (${publishedAt}). ` +
|
|
58
|
+
'Very new versions have had less community scrutiny.',
|
|
59
|
+
recommendation: 'Consider waiting for community feedback before adopting very new versions.',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else if (ageInDays < 30) {
|
|
63
|
+
findings.push({
|
|
64
|
+
analyzer: this.name,
|
|
65
|
+
severity: 'info',
|
|
66
|
+
title: 'Recently published version',
|
|
67
|
+
description: `This version was published ${Math.floor(ageInDays)} day(s) ago (${publishedAt}).`,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Check total number of versions as a maturity signal
|
|
72
|
+
const versionCount = context.registryMetadata.versions.length;
|
|
73
|
+
if (versionCount === 1) {
|
|
74
|
+
findings.push({
|
|
75
|
+
analyzer: this.name,
|
|
76
|
+
severity: 'low',
|
|
77
|
+
title: 'First published version',
|
|
78
|
+
description: 'This package has only one published version, indicating it is brand new.',
|
|
79
|
+
recommendation: 'New packages have had less vetting. Review the code carefully.',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
logger.warn(`[${this.name}] Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
85
|
+
}
|
|
86
|
+
return Promise.resolve({
|
|
87
|
+
analyzer: this.name,
|
|
88
|
+
findings,
|
|
89
|
+
duration: performance.now() - start,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/maintainer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Call Analyzer — detects outbound HTTP requests, WebSocket
|
|
3
|
+
* connections, hardcoded IPs, and imports of networking libraries.
|
|
4
|
+
*/
|
|
5
|
+
import type { Finding } from '../../core/types.js';
|
|
6
|
+
import { FileBasedAnalyzer } from '../file-based-analyzer.js';
|
|
7
|
+
export declare class NetworkCallsAnalyzer extends FileBasedAnalyzer {
|
|
8
|
+
readonly name = "network-calls";
|
|
9
|
+
readonly description = "Detects outbound network requests, hardcoded IPs, and networking library imports";
|
|
10
|
+
protected analyzeFile(source: string, relPath: string): Finding[];
|
|
11
|
+
private detectNetworkAPIs;
|
|
12
|
+
private detectNetworkImports;
|
|
13
|
+
private detectHardcodedIPs;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/network-calls/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAwB9D,qBAAa,oBAAqB,SAAQ,iBAAiB;IACzD,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,WAAW,sFACiE;IAErF,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE;IAUjE,OAAO,CAAC,iBAAiB;IAoGzB,OAAO,CAAC,oBAAoB;IA2D5B,OAAO,CAAC,kBAAkB;CAsC3B"}
|