verdaccio-security-filter 1.3.1 → 1.3.2
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/build/index.d.ts +0 -58
- package/build/index.js +1 -97
- package/build/lib/author-checker.d.ts +0 -19
- package/build/lib/author-checker.js +5 -31
- package/build/lib/cve-checker.d.ts +0 -37
- package/build/lib/cve-checker.js +0 -44
- package/build/lib/license-checker.d.ts +0 -21
- package/build/lib/license-checker.js +0 -30
- package/build/lib/logger.d.ts +0 -21
- package/build/lib/logger.js +0 -21
- package/build/lib/lru-cache.d.ts +0 -3
- package/build/lib/lru-cache.js +0 -3
- package/build/lib/metrics.d.ts +0 -36
- package/build/lib/metrics.js +0 -38
- package/build/lib/package-age-checker.d.ts +0 -22
- package/build/lib/package-age-checker.js +0 -29
- package/build/lib/whitelist-checker.d.ts +0 -26
- package/build/lib/whitelist-checker.js +0 -37
- package/build/types.d.ts +0 -3
- package/package.json +5 -3
package/build/lib/cve-checker.js
CHANGED
|
@@ -46,9 +46,6 @@ exports.CVEChecker = void 0;
|
|
|
46
46
|
const fs = __importStar(require("fs"));
|
|
47
47
|
const path = __importStar(require("path"));
|
|
48
48
|
const lru_cache_1 = require("./lru-cache");
|
|
49
|
-
/**
|
|
50
|
-
* CVE Checker that integrates with vulnerability databases
|
|
51
|
-
*/
|
|
52
49
|
class CVEChecker {
|
|
53
50
|
constructor(config) {
|
|
54
51
|
this.lastUpdate = 0;
|
|
@@ -68,9 +65,6 @@ class CVEChecker {
|
|
|
68
65
|
this.loadCache();
|
|
69
66
|
}
|
|
70
67
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Check if a package version has known vulnerabilities
|
|
73
|
-
*/
|
|
74
68
|
checkPackage(packageName, version) {
|
|
75
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
70
|
if (!this.config.enabled) {
|
|
@@ -83,13 +77,10 @@ class CVEChecker {
|
|
|
83
77
|
};
|
|
84
78
|
}
|
|
85
79
|
const cacheKey = `${packageName}@${version}`;
|
|
86
|
-
// Check cache first
|
|
87
80
|
if (this.cache.has(cacheKey) && !this.isCacheStale()) {
|
|
88
81
|
return this.cache.get(cacheKey);
|
|
89
82
|
}
|
|
90
|
-
// Fetch from databases
|
|
91
83
|
const vulnerabilities = yield this.fetchVulnerabilities(packageName, version);
|
|
92
|
-
// Filter by configured severity
|
|
93
84
|
const filteredVulnerabilities = vulnerabilities.filter(vuln => this.config.severity.includes(vuln.severity));
|
|
94
85
|
const result = {
|
|
95
86
|
package: packageName,
|
|
@@ -98,15 +89,11 @@ class CVEChecker {
|
|
|
98
89
|
isVulnerable: filteredVulnerabilities.length > 0,
|
|
99
90
|
checkedAt: new Date().toISOString(),
|
|
100
91
|
};
|
|
101
|
-
// Cache result
|
|
102
92
|
this.cache.set(cacheKey, result);
|
|
103
93
|
this.debouncedSaveCache();
|
|
104
94
|
return result;
|
|
105
95
|
});
|
|
106
96
|
}
|
|
107
|
-
/**
|
|
108
|
-
* Fetch vulnerabilities from configured databases
|
|
109
|
-
*/
|
|
110
97
|
fetchVulnerabilities(packageName, version) {
|
|
111
98
|
return __awaiter(this, void 0, void 0, function* () {
|
|
112
99
|
const vulnerabilities = [];
|
|
@@ -117,10 +104,8 @@ class CVEChecker {
|
|
|
117
104
|
vulnerabilities.push(...yield this.fetchFromOSV(packageName, version));
|
|
118
105
|
break;
|
|
119
106
|
case 'snyk':
|
|
120
|
-
// Snyk integration would go here (requires API key)
|
|
121
107
|
break;
|
|
122
108
|
case 'github':
|
|
123
|
-
// GitHub Advisory Database integration would go here
|
|
124
109
|
break;
|
|
125
110
|
}
|
|
126
111
|
}
|
|
@@ -132,10 +117,6 @@ class CVEChecker {
|
|
|
132
117
|
return vulnerabilities;
|
|
133
118
|
});
|
|
134
119
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Fetch vulnerabilities from OSV (Open Source Vulnerabilities) database
|
|
137
|
-
* https://osv.dev/
|
|
138
|
-
*/
|
|
139
120
|
fetchFromOSV(packageName, version) {
|
|
140
121
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
122
|
const maxRetries = 3;
|
|
@@ -203,20 +184,13 @@ class CVEChecker {
|
|
|
203
184
|
return [];
|
|
204
185
|
});
|
|
205
186
|
}
|
|
206
|
-
/**
|
|
207
|
-
* Sleep utility for retry delays
|
|
208
|
-
*/
|
|
209
187
|
sleep(ms) {
|
|
210
188
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
211
189
|
}
|
|
212
|
-
/**
|
|
213
|
-
* Map OSV severity to our severity levels
|
|
214
|
-
*/
|
|
215
190
|
mapOSVSeverity(osvSeverity) {
|
|
216
191
|
if (!osvSeverity || osvSeverity.length === 0) {
|
|
217
192
|
return 'medium';
|
|
218
193
|
}
|
|
219
|
-
// OSV uses CVSS scores
|
|
220
194
|
const severity = osvSeverity[0];
|
|
221
195
|
if (severity.type === 'CVSS_V3') {
|
|
222
196
|
const score = parseFloat(severity.score);
|
|
@@ -230,17 +204,11 @@ class CVEChecker {
|
|
|
230
204
|
}
|
|
231
205
|
return 'medium';
|
|
232
206
|
}
|
|
233
|
-
/**
|
|
234
|
-
* Check if cache is stale
|
|
235
|
-
*/
|
|
236
207
|
isCacheStale() {
|
|
237
208
|
const now = Date.now();
|
|
238
209
|
const updateIntervalMs = this.config.updateInterval * 60 * 60 * 1000;
|
|
239
210
|
return now - this.lastUpdate > updateIntervalMs;
|
|
240
211
|
}
|
|
241
|
-
/**
|
|
242
|
-
* Load cache from disk
|
|
243
|
-
*/
|
|
244
212
|
loadCache() {
|
|
245
213
|
try {
|
|
246
214
|
const cacheFile = path.join(this.config.cacheDir, 'cve-cache.json');
|
|
@@ -260,9 +228,6 @@ class CVEChecker {
|
|
|
260
228
|
console.error('[CVE Checker] Failed to load cache:', message);
|
|
261
229
|
}
|
|
262
230
|
}
|
|
263
|
-
/**
|
|
264
|
-
* Debounced save cache to reduce I/O operations
|
|
265
|
-
*/
|
|
266
231
|
debouncedSaveCache() {
|
|
267
232
|
if (this.saveTimer) {
|
|
268
233
|
clearTimeout(this.saveTimer);
|
|
@@ -272,9 +237,6 @@ class CVEChecker {
|
|
|
272
237
|
this.saveTimer = null;
|
|
273
238
|
}, this.SAVE_DEBOUNCE_MS);
|
|
274
239
|
}
|
|
275
|
-
/**
|
|
276
|
-
* Save cache to disk immediately
|
|
277
|
-
*/
|
|
278
240
|
saveCache() {
|
|
279
241
|
try {
|
|
280
242
|
const cacheFile = path.join(this.config.cacheDir, 'cve-cache.json');
|
|
@@ -294,17 +256,11 @@ class CVEChecker {
|
|
|
294
256
|
console.error('[CVE Checker] Failed to save cache:', message);
|
|
295
257
|
}
|
|
296
258
|
}
|
|
297
|
-
/**
|
|
298
|
-
* Clear cache
|
|
299
|
-
*/
|
|
300
259
|
clearCache() {
|
|
301
260
|
this.cache.clear();
|
|
302
261
|
this.lastUpdate = 0;
|
|
303
262
|
this.saveCache();
|
|
304
263
|
}
|
|
305
|
-
/**
|
|
306
|
-
* Cleanup resources
|
|
307
|
-
*/
|
|
308
264
|
destroy() {
|
|
309
265
|
if (this.saveTimer) {
|
|
310
266
|
clearTimeout(this.saveTimer);
|
|
@@ -1,37 +1,16 @@
|
|
|
1
1
|
import { LicenseConfig } from '../types';
|
|
2
2
|
import { Version } from '@verdaccio/types';
|
|
3
|
-
/**
|
|
4
|
-
* License checker for validating package licenses
|
|
5
|
-
*/
|
|
6
3
|
export declare class LicenseChecker {
|
|
7
4
|
private config;
|
|
8
5
|
constructor(config?: LicenseConfig);
|
|
9
|
-
/**
|
|
10
|
-
* Check if a package version's license is allowed
|
|
11
|
-
*/
|
|
12
6
|
checkLicense(versionData: Version): {
|
|
13
7
|
allowed: boolean;
|
|
14
8
|
reason?: string;
|
|
15
9
|
license?: string;
|
|
16
10
|
};
|
|
17
|
-
/**
|
|
18
|
-
* Extract license from version data
|
|
19
|
-
*/
|
|
20
11
|
private extractLicense;
|
|
21
|
-
/**
|
|
22
|
-
* Check if license is blocked
|
|
23
|
-
*/
|
|
24
12
|
private isLicenseBlocked;
|
|
25
|
-
/**
|
|
26
|
-
* Check if license is allowed
|
|
27
|
-
*/
|
|
28
13
|
private isLicenseAllowed;
|
|
29
|
-
/**
|
|
30
|
-
* Get common open source licenses
|
|
31
|
-
*/
|
|
32
14
|
static getCommonOpenSourceLicenses(): string[];
|
|
33
|
-
/**
|
|
34
|
-
* Get common copyleft licenses
|
|
35
|
-
*/
|
|
36
15
|
static getCopyleftLicenses(): string[];
|
|
37
16
|
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LicenseChecker = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* License checker for validating package licenses
|
|
6
|
-
*/
|
|
7
4
|
class LicenseChecker {
|
|
8
5
|
constructor(config) {
|
|
9
6
|
this.config = {
|
|
@@ -12,12 +9,8 @@ class LicenseChecker {
|
|
|
12
9
|
requireLicense: (config === null || config === void 0 ? void 0 : config.requireLicense) !== false,
|
|
13
10
|
};
|
|
14
11
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Check if a package version's license is allowed
|
|
17
|
-
*/
|
|
18
12
|
checkLicense(versionData) {
|
|
19
13
|
const license = this.extractLicense(versionData);
|
|
20
|
-
// Check if license is missing
|
|
21
14
|
if (!license || license === 'UNLICENSED' || license === '') {
|
|
22
15
|
if (this.config.requireLicense) {
|
|
23
16
|
return {
|
|
@@ -28,7 +21,6 @@ class LicenseChecker {
|
|
|
28
21
|
}
|
|
29
22
|
return { allowed: true };
|
|
30
23
|
}
|
|
31
|
-
// Check blocked list
|
|
32
24
|
if (this.isLicenseBlocked(license)) {
|
|
33
25
|
return {
|
|
34
26
|
allowed: false,
|
|
@@ -36,7 +28,6 @@ class LicenseChecker {
|
|
|
36
28
|
license,
|
|
37
29
|
};
|
|
38
30
|
}
|
|
39
|
-
// Check allowed list (if specified)
|
|
40
31
|
if (this.config.allowed.length > 0 && !this.isLicenseAllowed(license)) {
|
|
41
32
|
return {
|
|
42
33
|
allowed: false,
|
|
@@ -46,54 +37,36 @@ class LicenseChecker {
|
|
|
46
37
|
}
|
|
47
38
|
return { allowed: true, license };
|
|
48
39
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Extract license from version data
|
|
51
|
-
*/
|
|
52
40
|
extractLicense(versionData) {
|
|
53
41
|
if (!versionData.license) {
|
|
54
42
|
return null;
|
|
55
43
|
}
|
|
56
|
-
// Handle string license
|
|
57
44
|
if (typeof versionData.license === 'string') {
|
|
58
45
|
return versionData.license;
|
|
59
46
|
}
|
|
60
|
-
// Handle SPDX license object
|
|
61
47
|
if (typeof versionData.license === 'object' && 'type' in versionData.license) {
|
|
62
48
|
return versionData.license.type;
|
|
63
49
|
}
|
|
64
50
|
return null;
|
|
65
51
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Check if license is blocked
|
|
68
|
-
*/
|
|
69
52
|
isLicenseBlocked(license) {
|
|
70
53
|
return this.config.blocked.some(blocked => {
|
|
71
|
-
// Exact match
|
|
72
54
|
if (blocked === license) {
|
|
73
55
|
return true;
|
|
74
56
|
}
|
|
75
|
-
// Handle SPDX expressions (e.g., "MIT OR Apache-2.0")
|
|
76
57
|
const licenseTokens = license.split(/\s+(?:OR|AND)\s+/i);
|
|
77
58
|
return licenseTokens.some(token => token.trim() === blocked);
|
|
78
59
|
});
|
|
79
60
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Check if license is allowed
|
|
82
|
-
*/
|
|
83
61
|
isLicenseAllowed(license) {
|
|
84
62
|
return this.config.allowed.some(allowed => {
|
|
85
|
-
// Exact match
|
|
86
63
|
if (allowed === license) {
|
|
87
64
|
return true;
|
|
88
65
|
}
|
|
89
|
-
// Handle SPDX expressions (e.g., "MIT OR Apache-2.0")
|
|
90
66
|
const licenseTokens = license.split(/\s+(?:OR|AND)\s+/i);
|
|
91
67
|
return licenseTokens.some(token => token.trim() === allowed);
|
|
92
68
|
});
|
|
93
69
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Get common open source licenses
|
|
96
|
-
*/
|
|
97
70
|
static getCommonOpenSourceLicenses() {
|
|
98
71
|
return [
|
|
99
72
|
'MIT',
|
|
@@ -106,9 +79,6 @@ class LicenseChecker {
|
|
|
106
79
|
'Unlicense',
|
|
107
80
|
];
|
|
108
81
|
}
|
|
109
|
-
/**
|
|
110
|
-
* Get common copyleft licenses
|
|
111
|
-
*/
|
|
112
82
|
static getCopyleftLicenses() {
|
|
113
83
|
return [
|
|
114
84
|
'GPL-2.0',
|
package/build/lib/logger.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { Logger } from '@verdaccio/types';
|
|
2
2
|
import { LoggerConfig } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* Enhanced logger wrapper with configurable log levels and formatting
|
|
5
|
-
*/
|
|
6
3
|
export declare class SecurityLogger {
|
|
7
4
|
private verdaccioLogger;
|
|
8
5
|
private config;
|
|
@@ -15,28 +12,10 @@ export declare class SecurityLogger {
|
|
|
15
12
|
info(message: string, ...args: any[]): void;
|
|
16
13
|
warn(message: string, ...args: any[]): void;
|
|
17
14
|
error(message: string, ...args: any[]): void;
|
|
18
|
-
/**
|
|
19
|
-
* Log package blocking event
|
|
20
|
-
*/
|
|
21
15
|
logBlock(packageName: string, version: string, reason: string): void;
|
|
22
|
-
/**
|
|
23
|
-
* Log fallback event
|
|
24
|
-
*/
|
|
25
16
|
logFallback(packageName: string, fromVersion: string, toVersion: string, reason?: string): void;
|
|
26
|
-
/**
|
|
27
|
-
* Log CVE detection
|
|
28
|
-
*/
|
|
29
17
|
logCVE(packageName: string, version: string, cveId: string, severity: string): void;
|
|
30
|
-
/**
|
|
31
|
-
* Log license violation
|
|
32
|
-
*/
|
|
33
18
|
logLicense(packageName: string, version: string, license: string, reason: string): void;
|
|
34
|
-
/**
|
|
35
|
-
* Log publish rejection
|
|
36
|
-
*/
|
|
37
19
|
logPublishRejected(packageName: string, version: string, reason: string): void;
|
|
38
|
-
/**
|
|
39
|
-
* Log initialization
|
|
40
|
-
*/
|
|
41
20
|
logInit(features: string[]): void;
|
|
42
21
|
}
|
package/build/lib/logger.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SecurityLogger = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Enhanced logger wrapper with configurable log levels and formatting
|
|
6
|
-
*/
|
|
7
4
|
class SecurityLogger {
|
|
8
5
|
constructor(verdaccioLogger, config) {
|
|
9
6
|
this.prefix = '[Security Filter]';
|
|
@@ -54,40 +51,22 @@ class SecurityLogger {
|
|
|
54
51
|
this.verdaccioLogger.error(this.formatMessage(message), ...args);
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Log package blocking event
|
|
59
|
-
*/
|
|
60
54
|
logBlock(packageName, version, reason) {
|
|
61
55
|
this.warn(`Blocked ${packageName}@${version} - ${reason}`);
|
|
62
56
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Log fallback event
|
|
65
|
-
*/
|
|
66
57
|
logFallback(packageName, fromVersion, toVersion, reason) {
|
|
67
58
|
const reasonText = reason ? ` (${reason})` : '';
|
|
68
59
|
this.info(`Fallback applied: ${packageName}@${fromVersion} -> ${toVersion}${reasonText}`);
|
|
69
60
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Log CVE detection
|
|
72
|
-
*/
|
|
73
61
|
logCVE(packageName, version, cveId, severity) {
|
|
74
62
|
this.warn(`CVE detected: ${cveId} [${severity}] in ${packageName}@${version}`);
|
|
75
63
|
}
|
|
76
|
-
/**
|
|
77
|
-
* Log license violation
|
|
78
|
-
*/
|
|
79
64
|
logLicense(packageName, version, license, reason) {
|
|
80
65
|
this.warn(`License violation: ${packageName}@${version} has ${license} - ${reason}`);
|
|
81
66
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Log publish rejection
|
|
84
|
-
*/
|
|
85
67
|
logPublishRejected(packageName, version, reason) {
|
|
86
68
|
this.warn(`Publish rejected: ${packageName}@${version} - ${reason}`);
|
|
87
69
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Log initialization
|
|
90
|
-
*/
|
|
91
70
|
logInit(features) {
|
|
92
71
|
this.info(`Plugin initialized with features: ${features.join(', ')}`);
|
|
93
72
|
}
|
package/build/lib/lru-cache.d.ts
CHANGED
package/build/lib/lru-cache.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LRUCache = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Simple LRU (Least Recently Used) Cache implementation with size limits
|
|
6
|
-
*/
|
|
7
4
|
class LRUCache {
|
|
8
5
|
constructor(maxSize = 1000) {
|
|
9
6
|
this.cache = new Map();
|
package/build/lib/metrics.d.ts
CHANGED
|
@@ -1,55 +1,19 @@
|
|
|
1
1
|
import { MetricsConfig, MetricsData } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Metrics collector for tracking security events
|
|
4
|
-
*/
|
|
5
2
|
export declare class MetricsCollector {
|
|
6
3
|
private config;
|
|
7
4
|
private metricsBuffer;
|
|
8
5
|
private readonly bufferSize;
|
|
9
6
|
private readonly maxBufferSize;
|
|
10
7
|
constructor(config?: MetricsConfig);
|
|
11
|
-
/**
|
|
12
|
-
* Record a security event
|
|
13
|
-
*/
|
|
14
8
|
record(event: MetricsData): void;
|
|
15
|
-
/**
|
|
16
|
-
* Record a block event
|
|
17
|
-
*/
|
|
18
9
|
recordBlock(packageName: string, version: string, reason: string, metadata?: Record<string, any>): void;
|
|
19
|
-
/**
|
|
20
|
-
* Record a fallback event
|
|
21
|
-
*/
|
|
22
10
|
recordFallback(packageName: string, fromVersion: string, toVersion: string, reason: string): void;
|
|
23
|
-
/**
|
|
24
|
-
* Record a publish rejection
|
|
25
|
-
*/
|
|
26
11
|
recordPublishRejected(packageName: string, version: string, reason: string): void;
|
|
27
|
-
/**
|
|
28
|
-
* Record a CVE detection
|
|
29
|
-
*/
|
|
30
12
|
recordCVE(packageName: string, version: string, cveId: string, severity: string): void;
|
|
31
|
-
/**
|
|
32
|
-
* Record a license block
|
|
33
|
-
*/
|
|
34
13
|
recordLicenseBlock(packageName: string, version: string, license: string, reason: string): void;
|
|
35
|
-
/**
|
|
36
|
-
* Record a package-too-new event
|
|
37
|
-
*/
|
|
38
14
|
recordPackageTooNew(packageName: string, version: string, reason: string, metadata?: Record<string, any>): void;
|
|
39
|
-
/**
|
|
40
|
-
* Flush metrics buffer to output
|
|
41
|
-
*/
|
|
42
15
|
flush(): void;
|
|
43
|
-
/**
|
|
44
|
-
* Write metrics to file
|
|
45
|
-
*/
|
|
46
16
|
private writeToFile;
|
|
47
|
-
/**
|
|
48
|
-
* Get metrics summary
|
|
49
|
-
*/
|
|
50
17
|
getSummary(): Record<string, number>;
|
|
51
|
-
/**
|
|
52
|
-
* Cleanup - flush remaining metrics
|
|
53
|
-
*/
|
|
54
18
|
cleanup(): void;
|
|
55
19
|
}
|
package/build/lib/metrics.js
CHANGED
|
@@ -36,9 +36,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.MetricsCollector = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
|
-
/**
|
|
40
|
-
* Metrics collector for tracking security events
|
|
41
|
-
*/
|
|
42
39
|
class MetricsCollector {
|
|
43
40
|
constructor(config) {
|
|
44
41
|
this.metricsBuffer = [];
|
|
@@ -50,9 +47,6 @@ class MetricsCollector {
|
|
|
50
47
|
filePath: (config === null || config === void 0 ? void 0 : config.filePath) || './security-metrics.json',
|
|
51
48
|
};
|
|
52
49
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Record a security event
|
|
55
|
-
*/
|
|
56
50
|
record(event) {
|
|
57
51
|
if (!this.config.enabled) {
|
|
58
52
|
return;
|
|
@@ -65,9 +59,6 @@ class MetricsCollector {
|
|
|
65
59
|
this.flush();
|
|
66
60
|
}
|
|
67
61
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Record a block event
|
|
70
|
-
*/
|
|
71
62
|
recordBlock(packageName, version, reason, metadata) {
|
|
72
63
|
this.record({
|
|
73
64
|
timestamp: new Date().toISOString(),
|
|
@@ -78,9 +69,6 @@ class MetricsCollector {
|
|
|
78
69
|
metadata,
|
|
79
70
|
});
|
|
80
71
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Record a fallback event
|
|
83
|
-
*/
|
|
84
72
|
recordFallback(packageName, fromVersion, toVersion, reason) {
|
|
85
73
|
this.record({
|
|
86
74
|
timestamp: new Date().toISOString(),
|
|
@@ -91,9 +79,6 @@ class MetricsCollector {
|
|
|
91
79
|
metadata: { toVersion },
|
|
92
80
|
});
|
|
93
81
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Record a publish rejection
|
|
96
|
-
*/
|
|
97
82
|
recordPublishRejected(packageName, version, reason) {
|
|
98
83
|
this.record({
|
|
99
84
|
timestamp: new Date().toISOString(),
|
|
@@ -103,9 +88,6 @@ class MetricsCollector {
|
|
|
103
88
|
reason,
|
|
104
89
|
});
|
|
105
90
|
}
|
|
106
|
-
/**
|
|
107
|
-
* Record a CVE detection
|
|
108
|
-
*/
|
|
109
91
|
recordCVE(packageName, version, cveId, severity) {
|
|
110
92
|
this.record({
|
|
111
93
|
timestamp: new Date().toISOString(),
|
|
@@ -116,9 +98,6 @@ class MetricsCollector {
|
|
|
116
98
|
metadata: { cveId, severity },
|
|
117
99
|
});
|
|
118
100
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Record a license block
|
|
121
|
-
*/
|
|
122
101
|
recordLicenseBlock(packageName, version, license, reason) {
|
|
123
102
|
this.record({
|
|
124
103
|
timestamp: new Date().toISOString(),
|
|
@@ -129,9 +108,6 @@ class MetricsCollector {
|
|
|
129
108
|
metadata: { license },
|
|
130
109
|
});
|
|
131
110
|
}
|
|
132
|
-
/**
|
|
133
|
-
* Record a package-too-new event
|
|
134
|
-
*/
|
|
135
111
|
recordPackageTooNew(packageName, version, reason, metadata) {
|
|
136
112
|
this.record({
|
|
137
113
|
timestamp: new Date().toISOString(),
|
|
@@ -142,9 +118,6 @@ class MetricsCollector {
|
|
|
142
118
|
metadata,
|
|
143
119
|
});
|
|
144
120
|
}
|
|
145
|
-
/**
|
|
146
|
-
* Flush metrics buffer to output
|
|
147
|
-
*/
|
|
148
121
|
flush() {
|
|
149
122
|
if (this.metricsBuffer.length === 0) {
|
|
150
123
|
return;
|
|
@@ -159,18 +132,13 @@ class MetricsCollector {
|
|
|
159
132
|
}
|
|
160
133
|
this.metricsBuffer = [];
|
|
161
134
|
}
|
|
162
|
-
/**
|
|
163
|
-
* Write metrics to file
|
|
164
|
-
*/
|
|
165
135
|
writeToFile(metrics) {
|
|
166
136
|
try {
|
|
167
137
|
const filePath = this.config.filePath;
|
|
168
138
|
const dir = path.dirname(filePath);
|
|
169
|
-
// Ensure directory exists
|
|
170
139
|
if (!fs.existsSync(dir)) {
|
|
171
140
|
fs.mkdirSync(dir, { recursive: true });
|
|
172
141
|
}
|
|
173
|
-
// Append to file
|
|
174
142
|
const content = metrics.map(m => JSON.stringify(m)).join('\n') + '\n';
|
|
175
143
|
fs.appendFileSync(filePath, content, 'utf8');
|
|
176
144
|
}
|
|
@@ -179,9 +147,6 @@ class MetricsCollector {
|
|
|
179
147
|
console.error('[Security Filter] Failed to write metrics:', message);
|
|
180
148
|
}
|
|
181
149
|
}
|
|
182
|
-
/**
|
|
183
|
-
* Get metrics summary
|
|
184
|
-
*/
|
|
185
150
|
getSummary() {
|
|
186
151
|
const summary = {
|
|
187
152
|
block: 0,
|
|
@@ -197,9 +162,6 @@ class MetricsCollector {
|
|
|
197
162
|
});
|
|
198
163
|
return summary;
|
|
199
164
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Cleanup - flush remaining metrics
|
|
202
|
-
*/
|
|
203
165
|
cleanup() {
|
|
204
166
|
this.flush();
|
|
205
167
|
}
|
|
@@ -1,45 +1,23 @@
|
|
|
1
1
|
import { PackageAgeConfig } from '../types';
|
|
2
2
|
import { Package } from '@verdaccio/types';
|
|
3
|
-
/**
|
|
4
|
-
* Package age checker to protect against newly created malicious packages
|
|
5
|
-
*/
|
|
6
3
|
export declare class PackageAgeChecker {
|
|
7
4
|
private config;
|
|
8
5
|
constructor(config?: PackageAgeConfig);
|
|
9
|
-
/**
|
|
10
|
-
* Check if a package is old enough to be trusted
|
|
11
|
-
*/
|
|
12
6
|
checkPackageAge(packageData: Package): {
|
|
13
7
|
allowed: boolean;
|
|
14
8
|
reason?: string;
|
|
15
9
|
ageDays?: number;
|
|
16
10
|
warnOnly?: boolean;
|
|
17
11
|
};
|
|
18
|
-
/**
|
|
19
|
-
* Check if a specific version is old enough to be trusted
|
|
20
|
-
*/
|
|
21
12
|
checkVersionAge(packageData: Package, version: string): {
|
|
22
13
|
allowed: boolean;
|
|
23
14
|
reason?: string;
|
|
24
15
|
ageDays?: number;
|
|
25
16
|
warnOnly?: boolean;
|
|
26
17
|
};
|
|
27
|
-
/**
|
|
28
|
-
* Get package creation date from time field
|
|
29
|
-
* The 'created' field in package.time represents when the package was first published
|
|
30
|
-
*/
|
|
31
18
|
private getPackageCreationDate;
|
|
32
|
-
/**
|
|
33
|
-
* Get version publish date from time field
|
|
34
|
-
*/
|
|
35
19
|
private getVersionPublishDate;
|
|
36
|
-
/**
|
|
37
|
-
* Calculate age in days from a date
|
|
38
|
-
*/
|
|
39
20
|
private calculateAgeDays;
|
|
40
|
-
/**
|
|
41
|
-
* Get summary of configuration
|
|
42
|
-
*/
|
|
43
21
|
getSummary(): {
|
|
44
22
|
enabled: boolean;
|
|
45
23
|
minPackageAgeDays: number;
|