verdaccio-security-filter 1.3.1 → 1.3.3

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.
@@ -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',
@@ -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
  }
@@ -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
  }
@@ -1,6 +1,3 @@
1
- /**
2
- * Simple LRU (Least Recently Used) Cache implementation with size limits
3
- */
4
1
  export declare class LRUCache<K, V> {
5
2
  private cache;
6
3
  private readonly maxSize;
@@ -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();
@@ -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
  }
@@ -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;