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,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Extended security analysis module
|
|
4
|
+
* Additional checks: license, repo validation, maintainer trust, download anomalies
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.analyzeLicense = analyzeLicense;
|
|
8
|
+
exports.checkMaintainerTrust = checkMaintainerTrust;
|
|
9
|
+
exports.validateRepository = validateRepository;
|
|
10
|
+
exports.checkReleaseAnomalies = checkReleaseAnomalies;
|
|
11
|
+
exports.analyzeDependencies = analyzeDependencies;
|
|
12
|
+
exports.analyzeFileStructure = analyzeFileStructure;
|
|
13
|
+
exports.extendedAnalysis = extendedAnalysis;
|
|
14
|
+
const NPM_REGISTRY = 'https://registry.npmjs.org';
|
|
15
|
+
/** License risk classification */
|
|
16
|
+
const LICENSE_RISK = {
|
|
17
|
+
// High risk - requires source sharing or has legal issues
|
|
18
|
+
'gpl-3.0': { level: 'high', reason: 'GPLv3 - copyleft, may affect proprietary code' },
|
|
19
|
+
'gpl-2.0': { level: 'medium', reason: 'GPLv2 - copyleft' },
|
|
20
|
+
'agpl-3.0': { level: 'high', reason: 'AGPLv3 - strong copyleft, SaaS exposure' },
|
|
21
|
+
'lgpl-3.0': { level: 'medium', reason: 'LGPLv3 - more permissive than GPL' },
|
|
22
|
+
'mpl-2.0': { level: 'low', reason: 'Mozilla Public License' },
|
|
23
|
+
' EPL-2.0': { level: 'low', reason: 'Eclipse Public License' },
|
|
24
|
+
'eupl-1.2': { level: 'medium', reason: 'European Union Public License' },
|
|
25
|
+
// Low risk - permissive
|
|
26
|
+
'mit': { level: 'low', reason: 'Permissive' },
|
|
27
|
+
'bsd': { level: 'low', reason: 'Permissive' },
|
|
28
|
+
'apache-2.0': { level: 'low', reason: 'Permissive' },
|
|
29
|
+
'isc': { level: 'low', reason: 'Permissive' },
|
|
30
|
+
'unlicense': { level: 'low', reason: 'Public domain' },
|
|
31
|
+
// Suspicious - requires investigation
|
|
32
|
+
'custom': { level: 'medium', reason: 'Custom license - review required' },
|
|
33
|
+
'none': { level: 'high', reason: 'No license - copyright issues' },
|
|
34
|
+
'proprietary': { level: 'high', reason: 'Proprietary - may restrict use' }
|
|
35
|
+
};
|
|
36
|
+
/** Known package maintainers with trust scores */
|
|
37
|
+
const TRUSTED_MAINTAINERS = new Set([
|
|
38
|
+
// Popular package maintainers
|
|
39
|
+
'ljharb', // Jordan Harband (lodash)
|
|
40
|
+
'sindresorhus', // Sindre Sohrus
|
|
41
|
+
'jdalton', // John-David Dalton (lodash creator)
|
|
42
|
+
'substack',
|
|
43
|
+
'juliangruber',
|
|
44
|
+
'rvagg',
|
|
45
|
+
'addaleax',
|
|
46
|
+
'bnb',
|
|
47
|
+
'fy',
|
|
48
|
+
'watson',
|
|
49
|
+
'leorom',
|
|
50
|
+
'd3',
|
|
51
|
+
'mbostock',
|
|
52
|
+
'mikaelbr',
|
|
53
|
+
'analog',
|
|
54
|
+
// Large organizations
|
|
55
|
+
'facebook',
|
|
56
|
+
'google',
|
|
57
|
+
'microsoft',
|
|
58
|
+
'amazon',
|
|
59
|
+
'netflix',
|
|
60
|
+
'stripe',
|
|
61
|
+
'paypal',
|
|
62
|
+
'twitter',
|
|
63
|
+
'uber'
|
|
64
|
+
]);
|
|
65
|
+
/** Suspicious TLDs for typosquatting detection */
|
|
66
|
+
const SUSPICIOUS_TLDS = ['xyz', 'app', 'dev', 'io', 'co', 'sh', 'js', 'cn', 'ru'];
|
|
67
|
+
/**
|
|
68
|
+
* Analyze license risk
|
|
69
|
+
*/
|
|
70
|
+
function analyzeLicense(license) {
|
|
71
|
+
if (!license) {
|
|
72
|
+
return {
|
|
73
|
+
risk: 'high',
|
|
74
|
+
details: 'No license specified - copyright issues',
|
|
75
|
+
permissive: false
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Normalize license string
|
|
79
|
+
const normalized = license.toString().replace(/^(\d+\.)+/, '').trim().toLowerCase();
|
|
80
|
+
const known = LICENSE_RISK[normalized];
|
|
81
|
+
if (known) {
|
|
82
|
+
return {
|
|
83
|
+
risk: known.level,
|
|
84
|
+
details: known.reason,
|
|
85
|
+
permissive: known.level === 'low'
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Check for OR patterns (multiple licenses)
|
|
89
|
+
if (license.includes(' OR ')) {
|
|
90
|
+
return {
|
|
91
|
+
risk: 'medium',
|
|
92
|
+
details: 'Multiple licenses - review required',
|
|
93
|
+
permissive: false
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
risk: 'low',
|
|
98
|
+
details: 'Unknown but present',
|
|
99
|
+
permissive: true
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check if maintainer is trusted/known
|
|
104
|
+
*/
|
|
105
|
+
function checkMaintainerTrust(maintainers, publisher) {
|
|
106
|
+
const allAuthors = [...(maintainers || []), publisher].filter(Boolean);
|
|
107
|
+
const names = allAuthors.map(m => m.username || m.name).filter(Boolean);
|
|
108
|
+
if (names.length === 0) {
|
|
109
|
+
return {
|
|
110
|
+
score: 0,
|
|
111
|
+
isTrusted: false,
|
|
112
|
+
details: 'No maintainers identified'
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// Check if any trusted maintainer
|
|
116
|
+
const trustedCount = names.filter(n => TRUSTED_MAINTAINERS.has(n.toLowerCase())).length;
|
|
117
|
+
const trustRatio = trustedCount / names.length;
|
|
118
|
+
if (trustRatio > 0.5) {
|
|
119
|
+
return {
|
|
120
|
+
score: 100,
|
|
121
|
+
isTrusted: true,
|
|
122
|
+
details: `${trustedCount} trusted maintainer(s): ${names.join(', ')}`
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (trustedCount > 0) {
|
|
126
|
+
return {
|
|
127
|
+
score: 50,
|
|
128
|
+
isTrusted: false,
|
|
129
|
+
details: `Some trusted maintainer(s): ${names.join(', ')}`
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
score: 20,
|
|
134
|
+
isTrusted: false,
|
|
135
|
+
details: `Unknown maintainer(s): ${names.join(', ')}`
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Validate repository URL exists and matches package
|
|
140
|
+
*/
|
|
141
|
+
async function validateRepository(repoUrl, packageName) {
|
|
142
|
+
const issues = [];
|
|
143
|
+
if (!repoUrl) {
|
|
144
|
+
return {
|
|
145
|
+
valid: false,
|
|
146
|
+
details: 'No repository URL',
|
|
147
|
+
issues: ['missing repository']
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Parse different repo formats
|
|
151
|
+
let normalizedUrl = repoUrl;
|
|
152
|
+
// Handle shorthand
|
|
153
|
+
if (!repoUrl.startsWith('http')) {
|
|
154
|
+
if (repoUrl.startsWith('github:')) {
|
|
155
|
+
normalizedUrl = 'https://' + repoUrl.replace('github:', '');
|
|
156
|
+
}
|
|
157
|
+
else if (repoUrl.startsWith('gist:')) {
|
|
158
|
+
normalizedUrl = 'https://gist.github.com/' + repoUrl.replace('gist:', '');
|
|
159
|
+
}
|
|
160
|
+
else if (repoUrl.startsWith('bitbucket:')) {
|
|
161
|
+
normalizedUrl = 'https://bitbucket.org/' + repoUrl.replace('bitbucket:', '');
|
|
162
|
+
}
|
|
163
|
+
else if (repoUrl.startsWith('gitlab:')) {
|
|
164
|
+
normalizedUrl = 'https://gitlab.com/' + repoUrl.replace('gitlab:', '');
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
normalizedUrl = 'https://' + repoUrl;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Extract owner/repo for GitHub
|
|
171
|
+
const githubMatch = normalizedUrl.match(/github\.com[/:]([\w-]+)\/([\w-.]+)/);
|
|
172
|
+
if (githubMatch) {
|
|
173
|
+
const [, owner, repo] = githubMatch;
|
|
174
|
+
const cleanRepo = repo.replace(/\.git$/, '');
|
|
175
|
+
// Check if repo name roughly matches package name
|
|
176
|
+
const expectedPackage = packageName.replace(/^@[\w-]+\//, ''); // Handle scoped packages
|
|
177
|
+
const nameMatch = cleanRepo.toLowerCase() === expectedPackage.toLowerCase() ||
|
|
178
|
+
cleanRepo.toLowerCase() === expectedPackage.replace(/[-_]/g, '').toLowerCase();
|
|
179
|
+
if (!nameMatch) {
|
|
180
|
+
issues.push(`repo name "${cleanRepo}" != package "${expectedPackage}"`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Check for suspicious domains
|
|
184
|
+
const url = new URL(normalizedUrl);
|
|
185
|
+
if (SUSPICIOUS_TLDS.includes(url.hostname.split('.').pop() || '')) {
|
|
186
|
+
issues.push(`suspicious TLD: ${url.hostname}`);
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
valid: issues.length === 0,
|
|
190
|
+
details: normalizedUrl,
|
|
191
|
+
issues
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check for release anomalies (sudden popularity spike = typosquatting indicator)
|
|
196
|
+
*/
|
|
197
|
+
async function checkReleaseAnomalies(packageName, metadata) {
|
|
198
|
+
const metrics = {
|
|
199
|
+
versionCount: 0,
|
|
200
|
+
hasNewVersions: false,
|
|
201
|
+
rapidRelease: false
|
|
202
|
+
};
|
|
203
|
+
try {
|
|
204
|
+
// Fetch full package data
|
|
205
|
+
const response = await fetch(`${NPM_REGISTRY}/${packageName}`);
|
|
206
|
+
const data = await response.json();
|
|
207
|
+
const versions = Object.keys(data.versions || {});
|
|
208
|
+
metrics.versionCount = versions.length;
|
|
209
|
+
// Check for recent rapid releases (potential automated publishing)
|
|
210
|
+
if (data.time) {
|
|
211
|
+
const timeKeys = Object.keys(data.time).filter(k => k !== 'created' && k !== 'modified');
|
|
212
|
+
if (timeKeys.length > 1) {
|
|
213
|
+
const sorted = timeKeys.sort((a, b) => new Date(data.time[a]).getTime() - new Date(data.time[b]).getTime());
|
|
214
|
+
// Check if multiple releases within hours
|
|
215
|
+
if (sorted.length >= 2) {
|
|
216
|
+
const lastRelease = new Date(data.time[sorted[sorted.length - 1]]);
|
|
217
|
+
const prevRelease = new Date(data.time[sorted[sorted.length - 2]]);
|
|
218
|
+
const hoursApart = (lastRelease.getTime() - prevRelease.getTime()) / (1000 * 60 * 60);
|
|
219
|
+
if (hoursApart < 1) {
|
|
220
|
+
metrics.rapidRelease = true;
|
|
221
|
+
metrics.hoursApart = hoursApart;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
228
|
+
// Ignore - just for metrics
|
|
229
|
+
}
|
|
230
|
+
const suspicious = metrics.rapidRelease;
|
|
231
|
+
return {
|
|
232
|
+
suspicious,
|
|
233
|
+
details: suspicious ? 'Unusual rapid release pattern' : 'Normal release pattern',
|
|
234
|
+
metrics
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Analyze dependencies for freshness and known issues
|
|
239
|
+
*/
|
|
240
|
+
function analyzeDependencies(dependencies, devDependencies) {
|
|
241
|
+
const allDeps = { ...dependencies, ...devDependencies };
|
|
242
|
+
const issues = [];
|
|
243
|
+
const details = [];
|
|
244
|
+
if (!allDeps || Object.keys(allDeps).length === 0) {
|
|
245
|
+
return { outdatedCount: 0, issues: [], details: [] };
|
|
246
|
+
}
|
|
247
|
+
// Check for very old/deprecated packages
|
|
248
|
+
const deprecated = [
|
|
249
|
+
'request', // Deprecated in favor of fetch, axios
|
|
250
|
+
'moment', // Deprecated in favor of date-fns, dayjs
|
|
251
|
+
'lodash', // Should use lodash-es for tree-shaking
|
|
252
|
+
'querystring', // Built into Node.js
|
|
253
|
+
'underscore' // Use lodash or native
|
|
254
|
+
];
|
|
255
|
+
for (const [dep, ver] of Object.entries(allDeps)) {
|
|
256
|
+
if (deprecated.includes(dep)) {
|
|
257
|
+
issues.push(`${dep} is deprecated or not recommended`);
|
|
258
|
+
details.push(`${dep}@${ver}: consider alternatives`);
|
|
259
|
+
}
|
|
260
|
+
// Check for very old major versions still in use
|
|
261
|
+
if (ver.startsWith('^0.') || ver.startsWith('~0.')) {
|
|
262
|
+
issues.push(`${dep} using old major version`);
|
|
263
|
+
details.push(`${dep}@${ver}: may have vulnerabilities`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
outdatedCount: issues.length,
|
|
268
|
+
issues,
|
|
269
|
+
details
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Check file structure for suspicious patterns
|
|
274
|
+
*/
|
|
275
|
+
function analyzeFileStructure(files) {
|
|
276
|
+
const issues = [];
|
|
277
|
+
// Check for hidden files that shouldn't be there
|
|
278
|
+
const suspiciousFiles = [
|
|
279
|
+
/^\./,
|
|
280
|
+
/\.sh$/,
|
|
281
|
+
/\.bash$/,
|
|
282
|
+
/ bash/,
|
|
283
|
+
/script/i
|
|
284
|
+
];
|
|
285
|
+
// Check for common attack vectors
|
|
286
|
+
const suspiciousPaths = [
|
|
287
|
+
/proc\/self/,
|
|
288
|
+
/\/etc\//,
|
|
289
|
+
/~\/ /,
|
|
290
|
+
/\$HOME/,
|
|
291
|
+
/\.ssh\//
|
|
292
|
+
];
|
|
293
|
+
for (const file of files) {
|
|
294
|
+
for (const pattern of suspiciousPaths) {
|
|
295
|
+
if (pattern.test(file)) {
|
|
296
|
+
issues.push(`suspicious path: ${file}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
suspicious: issues.length > 0,
|
|
302
|
+
issues
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Combined extended analysis (sync parts only)
|
|
307
|
+
*/
|
|
308
|
+
function extendedAnalysis(packageName, metadata) {
|
|
309
|
+
const license = analyzeLicense(metadata.license);
|
|
310
|
+
const maintainer = checkMaintainerTrust(metadata.maintainers, metadata.publisher);
|
|
311
|
+
const dependencies = analyzeDependencies(metadata.dependencies, metadata.devDependencies);
|
|
312
|
+
return { license, maintainer, repository: { valid: true, details: '', issues: [] }, dependencies };
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=extended.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extended.js","sourceRoot":"","sources":["../../src/lib/extended.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Package integrity verification
|
|
4
|
+
* Hash verification, signature checking, tarball analysis
|
|
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.verifyIntegrity = verifyIntegrity;
|
|
41
|
+
exports.analyzePackageSize = analyzePackageSize;
|
|
42
|
+
exports.analyzeTarball = analyzeTarball;
|
|
43
|
+
exports.fullIntegrityCheck = fullIntegrityCheck;
|
|
44
|
+
const crypto = __importStar(require("crypto"));
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const tar = __importStar(require("tar"));
|
|
49
|
+
const NPM_REGISTRY = 'https://registry.npmjs.org';
|
|
50
|
+
/**
|
|
51
|
+
* Verify package integrity using npm registry integrity field
|
|
52
|
+
*/
|
|
53
|
+
async function verifyIntegrity(packageName, version, registry = NPM_REGISTRY) {
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(`${registry}/${packageName}/${version}`);
|
|
56
|
+
const data = await response.json();
|
|
57
|
+
const expectedHash = data.dist?.integrity || null;
|
|
58
|
+
if (!expectedHash) {
|
|
59
|
+
return {
|
|
60
|
+
valid: true,
|
|
61
|
+
expectedHash: null,
|
|
62
|
+
actualHash: null,
|
|
63
|
+
algorithm: 'none',
|
|
64
|
+
details: 'No integrity hash in registry'
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const algorithm = expectedHash.startsWith('sha512') ? 'sha512' : 'sha256';
|
|
68
|
+
const tarballUrl = data.dist?.tarball;
|
|
69
|
+
if (!tarballUrl) {
|
|
70
|
+
return {
|
|
71
|
+
valid: false,
|
|
72
|
+
expectedHash,
|
|
73
|
+
actualHash: null,
|
|
74
|
+
algorithm,
|
|
75
|
+
details: 'No tarball URL found'
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const tarballResponse = await fetch(tarballUrl);
|
|
79
|
+
const buffer = Buffer.from(await tarballResponse.arrayBuffer());
|
|
80
|
+
const actualHash = algorithm === 'sha512'
|
|
81
|
+
? 'sha512-' + crypto.createHash('sha512').update(buffer).digest('base64')
|
|
82
|
+
: 'sha256-' + crypto.createHash('sha256').update(buffer).digest('base64');
|
|
83
|
+
const valid = actualHash === expectedHash;
|
|
84
|
+
return {
|
|
85
|
+
valid,
|
|
86
|
+
expectedHash,
|
|
87
|
+
actualHash,
|
|
88
|
+
algorithm,
|
|
89
|
+
details: valid ? 'Integrity verified' : 'Integrity mismatch!'
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return {
|
|
94
|
+
valid: false,
|
|
95
|
+
expectedHash: null,
|
|
96
|
+
actualHash: null,
|
|
97
|
+
algorithm: 'none',
|
|
98
|
+
details: `Verification failed: ${error.message}`
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Analyze package size for anomalies
|
|
104
|
+
*/
|
|
105
|
+
async function analyzePackageSize(packageName, version, registry = NPM_REGISTRY) {
|
|
106
|
+
const THRESHOLD_MB = 50;
|
|
107
|
+
try {
|
|
108
|
+
const response = await fetch(`${registry}/${packageName}/${version}`);
|
|
109
|
+
const data = await response.json();
|
|
110
|
+
const size = data.dist?.unpackedSize || data.dist?.size || 0;
|
|
111
|
+
const sizeFormatted = formatBytes(size);
|
|
112
|
+
return {
|
|
113
|
+
size,
|
|
114
|
+
sizeFormatted,
|
|
115
|
+
suspicious: size > THRESHOLD_MB * 1024 * 1024,
|
|
116
|
+
threshold: THRESHOLD_MB,
|
|
117
|
+
details: size > THRESHOLD_MB * 1024 * 1024
|
|
118
|
+
? `Package size ${sizeFormatted} exceeds ${THRESHOLD_MB}MB threshold`
|
|
119
|
+
: `Package size ${sizeFormatted} is normal`
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
return {
|
|
124
|
+
size: 0,
|
|
125
|
+
sizeFormatted: '0 B',
|
|
126
|
+
suspicious: false,
|
|
127
|
+
threshold: THRESHOLD_MB,
|
|
128
|
+
details: 'Could not determine package size'
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Extract and analyze package.json from tarball
|
|
134
|
+
*/
|
|
135
|
+
async function analyzeTarball(packageName, version, registry = NPM_REGISTRY) {
|
|
136
|
+
const tempDir = path.join(os.tmpdir(), `npm-scan-tarball-${Date.now()}`);
|
|
137
|
+
const tarballPath = path.join(tempDir, 'package.tgz');
|
|
138
|
+
try {
|
|
139
|
+
const response = await fetch(`${registry}/${packageName}/${version}`);
|
|
140
|
+
const data = await response.json();
|
|
141
|
+
const tarballUrl = data.dist?.tarball;
|
|
142
|
+
if (!tarballUrl) {
|
|
143
|
+
return {
|
|
144
|
+
hasPkgJson: false,
|
|
145
|
+
main: null,
|
|
146
|
+
bin: {},
|
|
147
|
+
files: [],
|
|
148
|
+
fileCount: 0,
|
|
149
|
+
hasNativeCode: false,
|
|
150
|
+
details: 'No tarball URL'
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
154
|
+
const tarballResponse = await fetch(tarballUrl);
|
|
155
|
+
fs.writeFileSync(tarballPath, Buffer.from(await tarballResponse.arrayBuffer()));
|
|
156
|
+
const extractDir = path.join(tempDir, 'extracted');
|
|
157
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
158
|
+
await tar.extract({
|
|
159
|
+
file: tarballPath,
|
|
160
|
+
cwd: extractDir
|
|
161
|
+
});
|
|
162
|
+
const entries = fs.readdirSync(extractDir);
|
|
163
|
+
const pkgDir = entries.find(e => e.startsWith('package'));
|
|
164
|
+
const packageJsonPath = path.join(extractDir, pkgDir || '', 'package.json');
|
|
165
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
166
|
+
return {
|
|
167
|
+
hasPkgJson: false,
|
|
168
|
+
main: null,
|
|
169
|
+
bin: {},
|
|
170
|
+
files: [],
|
|
171
|
+
fileCount: 0,
|
|
172
|
+
hasNativeCode: false,
|
|
173
|
+
details: 'package.json not found in tarball'
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const pkgJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
177
|
+
const allFiles = getAllFiles(path.join(extractDir, pkgDir || ''));
|
|
178
|
+
const nativeExtensions = ['.node', '.dll', '.dylib', '.so', '.a', '.o'];
|
|
179
|
+
const hasNativeCode = allFiles.some(f => nativeExtensions.some(ext => f.endsWith(ext)));
|
|
180
|
+
return {
|
|
181
|
+
hasPkgJson: true,
|
|
182
|
+
main: pkgJson.main || null,
|
|
183
|
+
bin: pkgJson.bin || {},
|
|
184
|
+
files: allFiles,
|
|
185
|
+
fileCount: allFiles.length,
|
|
186
|
+
hasNativeCode,
|
|
187
|
+
details: hasNativeCode ? 'Contains native code' : 'Pure JavaScript'
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
return {
|
|
192
|
+
hasPkgJson: false,
|
|
193
|
+
main: null,
|
|
194
|
+
bin: {},
|
|
195
|
+
files: [],
|
|
196
|
+
fileCount: 0,
|
|
197
|
+
hasNativeCode: false,
|
|
198
|
+
details: `Analysis failed: ${error.message}`
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
try {
|
|
203
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
204
|
+
}
|
|
205
|
+
catch (e) { }
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function formatBytes(bytes) {
|
|
209
|
+
if (bytes === 0)
|
|
210
|
+
return '0 B';
|
|
211
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
212
|
+
let unitIndex = 0;
|
|
213
|
+
let size = bytes;
|
|
214
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
215
|
+
size = size / 1024;
|
|
216
|
+
unitIndex++;
|
|
217
|
+
}
|
|
218
|
+
return size.toFixed(2) + ' ' + units[unitIndex];
|
|
219
|
+
}
|
|
220
|
+
function getAllFiles(dir, baseDir) {
|
|
221
|
+
const files = [];
|
|
222
|
+
const base = baseDir || dir;
|
|
223
|
+
try {
|
|
224
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
225
|
+
for (const entry of entries) {
|
|
226
|
+
const fullPath = path.join(dir, entry.name);
|
|
227
|
+
const relativePath = path.relative(base, fullPath);
|
|
228
|
+
if (entry.isDirectory()) {
|
|
229
|
+
files.push(...getAllFiles(fullPath, base));
|
|
230
|
+
}
|
|
231
|
+
else if (entry.isFile()) {
|
|
232
|
+
files.push(relativePath);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (e) { }
|
|
237
|
+
return files;
|
|
238
|
+
}
|
|
239
|
+
async function fullIntegrityCheck(packageName, version, registry) {
|
|
240
|
+
const [integrity, size, tarball] = await Promise.all([
|
|
241
|
+
verifyIntegrity(packageName, version, registry),
|
|
242
|
+
analyzePackageSize(packageName, version, registry),
|
|
243
|
+
analyzeTarball(packageName, version, registry)
|
|
244
|
+
]);
|
|
245
|
+
return { integrity, size, tarball };
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../../src/lib/integrity.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaH,0CA2DC;AAKD,gDAgCC;AAKD,wCAoFC;AAuCD,gDAYC;AAvPD,+CAAiC;AACjC,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AACzB,yCAA2B;AAE3B,MAAM,YAAY,GAAG,4BAA4B,CAAC;AAElD;;GAEG;AACI,KAAK,UAAU,eAAe,CACnC,WAAmB,EACnB,OAAe,EACf,WAAmB,YAAY;IAE/B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,IAAI,WAAW,IAAI,OAAO,EAAE,CAAC,CAAC;QACtE,MAAM,IAAI,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAExC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC;QAElD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO;gBACL,KAAK,EAAE,IAAI;gBACX,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,IAAI;gBAChB,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,+BAA+B;aACzC,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;QAEtC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,YAAY;gBACZ,UAAU,EAAE,IAAI;gBAChB,SAAS;gBACT,OAAO,EAAE,sBAAsB;aAChC,CAAC;QACJ,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;QAEhE,MAAM,UAAU,GAAG,SAAS,KAAK,QAAQ;YACvC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;YACzE,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE5E,MAAM,KAAK,GAAG,UAAU,KAAK,YAAY,CAAC;QAE1C,OAAO;YACL,KAAK;YACL,YAAY;YACZ,UAAU;YACV,SAAS;YACT,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,qBAAqB;SAC9D,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,wBAAwB,KAAK,CAAC,OAAO,EAAE;SACjD,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,OAAe,EACf,WAAmB,YAAY;IAE/B,MAAM,YAAY,GAAG,EAAE,CAAC;IAExB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,IAAI,WAAW,IAAI,OAAO,EAAE,CAAC,CAAC;QACtE,MAAM,IAAI,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAExC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC;QAC7D,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAExC,OAAO;YACL,IAAI;YACJ,aAAa;YACb,UAAU,EAAE,IAAI,GAAG,YAAY,GAAG,IAAI,GAAG,IAAI;YAC7C,SAAS,EAAE,YAAY;YACvB,OAAO,EAAE,IAAI,GAAG,YAAY,GAAG,IAAI,GAAG,IAAI;gBACxC,CAAC,CAAC,gBAAgB,aAAa,YAAY,YAAY,cAAc;gBACrE,CAAC,CAAC,gBAAgB,aAAa,YAAY;SAC9C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,IAAI,EAAE,CAAC;YACP,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,KAAK;YACjB,SAAS,EAAE,YAAY;YACvB,OAAO,EAAE,kCAAkC;SAC5C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,cAAc,CAClC,WAAmB,EACnB,OAAe,EACf,WAAmB,YAAY;IAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAEtD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,IAAI,WAAW,IAAI,OAAO,EAAE,CAAC,CAAC;QACtE,MAAM,IAAI,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAExC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;QACtC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;gBACL,UAAU,EAAE,KAAK;gBACjB,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,EAAE;gBACP,KAAK,EAAE,EAAE;gBACT,SAAS,EAAE,CAAC;gBACZ,aAAa,EAAE,KAAK;gBACpB,OAAO,EAAE,gBAAgB;aAC1B,CAAC;QACJ,CAAC;QAED,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QAChD,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAEhF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACnD,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,MAAM,GAAG,CAAC,OAAO,CAAC;YAChB,IAAI,EAAE,WAAW;YACjB,GAAG,EAAE,UAAU;SAChB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1D,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,IAAI,EAAE,EAAE,cAAc,CAAC,CAAC;QAE5E,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YACpC,OAAO;gBACL,UAAU,EAAE,KAAK;gBACjB,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,EAAE;gBACP,KAAK,EAAE,EAAE;gBACT,SAAS,EAAE,CAAC;gBACZ,aAAa,EAAE,KAAK;gBACpB,OAAO,EAAE,mCAAmC;aAC7C,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QAElE,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACxE,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExF,OAAO;YACL,UAAU,EAAE,IAAI;YAChB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;YAC1B,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE;YACtB,KAAK,EAAE,QAAQ;YACf,SAAS,EAAE,QAAQ,CAAC,MAAM;YAC1B,aAAa;YACb,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,iBAAiB;SACpE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,EAAE;YACP,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,CAAC;YACZ,aAAa,EAAE,KAAK;YACpB,OAAO,EAAE,oBAAoB,KAAK,CAAC,OAAO,EAAE;SAC7C,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE9B,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,IAAI,GAAG,KAAK,CAAC;IAEjB,OAAO,IAAI,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;QACnB,SAAS,EAAE,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,OAAgB;IAChD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,OAAO,IAAI,GAAG,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAEnD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;YAC7C,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC;IAEd,OAAO,KAAK,CAAC;AACf,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,OAAe,EACf,QAAiB;IAEjB,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACnD,eAAe,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC;QAC/C,kBAAkB,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC;QAClD,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC;KAC/C,CAAC,CAAC;IAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detection patterns for malicious code, obfuscation, and suspicious behavior
|
|
3
|
+
*/
|
|
4
|
+
import type { FileThreat, ThreatType } from '../types';
|
|
5
|
+
declare const OBFUSCATION_PATTERNS: ({
|
|
6
|
+
pattern: RegExp;
|
|
7
|
+
type: ThreatType;
|
|
8
|
+
severity: "high";
|
|
9
|
+
message: string;
|
|
10
|
+
} | {
|
|
11
|
+
pattern: RegExp;
|
|
12
|
+
type: ThreatType;
|
|
13
|
+
severity: "medium";
|
|
14
|
+
message: string;
|
|
15
|
+
} | {
|
|
16
|
+
pattern: RegExp;
|
|
17
|
+
type: ThreatType;
|
|
18
|
+
severity: "low";
|
|
19
|
+
message: string;
|
|
20
|
+
})[];
|
|
21
|
+
declare const SUSPICIOUS_PATTERNS: ({
|
|
22
|
+
pattern: RegExp;
|
|
23
|
+
type: ThreatType;
|
|
24
|
+
severity: "critical";
|
|
25
|
+
message: string;
|
|
26
|
+
} | {
|
|
27
|
+
pattern: RegExp;
|
|
28
|
+
type: ThreatType;
|
|
29
|
+
severity: "high";
|
|
30
|
+
message: string;
|
|
31
|
+
} | {
|
|
32
|
+
pattern: RegExp;
|
|
33
|
+
type: ThreatType;
|
|
34
|
+
severity: "medium";
|
|
35
|
+
message: string;
|
|
36
|
+
} | {
|
|
37
|
+
pattern: RegExp;
|
|
38
|
+
type: ThreatType;
|
|
39
|
+
severity: "low";
|
|
40
|
+
message: string;
|
|
41
|
+
})[];
|
|
42
|
+
declare const SUSPICIOUS_SCRIPTS: ({
|
|
43
|
+
script: string;
|
|
44
|
+
severity: "high";
|
|
45
|
+
message: string;
|
|
46
|
+
} | {
|
|
47
|
+
script: string;
|
|
48
|
+
severity: "medium";
|
|
49
|
+
message: string;
|
|
50
|
+
} | {
|
|
51
|
+
script: string;
|
|
52
|
+
severity: "low";
|
|
53
|
+
message: string;
|
|
54
|
+
})[];
|
|
55
|
+
declare const SENSITIVE_FILES: RegExp[];
|
|
56
|
+
declare const CODE_EXTENSIONS: string[];
|
|
57
|
+
export interface PatternMatch {
|
|
58
|
+
pattern: RegExp;
|
|
59
|
+
type: ThreatType;
|
|
60
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
61
|
+
message: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Scan a single file for suspicious patterns
|
|
65
|
+
*/
|
|
66
|
+
export declare function scanFile(filePath: string, content: string): FileThreat[];
|
|
67
|
+
/**
|
|
68
|
+
* Check package.json scripts for suspicious behavior
|
|
69
|
+
*/
|
|
70
|
+
export declare function scanPackageJsonScripts(scripts: Record<string, string>): FileThreat[];
|
|
71
|
+
/**
|
|
72
|
+
* Scan directory for all files
|
|
73
|
+
*/
|
|
74
|
+
export declare function scanDirectory(dirPath: string, extensions?: string[]): Map<string, string>;
|
|
75
|
+
export { OBFUSCATION_PATTERNS, SUSPICIOUS_PATTERNS, SUSPICIOUS_SCRIPTS, SENSITIVE_FILES, CODE_EXTENSIONS };
|
|
76
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/lib/patterns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGvD,QAAA,MAAM,oBAAoB;;UAGC,UAAU;;;;;UAkBV,UAAU;;;;;UAwBV,UAAU;;;IAIpC,CAAC;AAGF,QAAA,MAAM,mBAAmB;;UAGM,UAAU;;;;;UAMV,UAAU;;;;;UAkBV,UAAU;;;;;UAYV,UAAU;;;IAkExC,CAAC;AAGF,QAAA,MAAM,kBAAkB;;;;;;;;;;;;IAmDvB,CAAC;AAGF,QAAA,MAAM,eAAe,UAsBpB,CAAC;AAGF,QAAA,MAAM,eAAe,UAKpB,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACjD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAwDxE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,EAAE,CAyBpF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuCzF;AAED,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,eAAe,EAChB,CAAC"}
|