verdaccio-security-filter 0.0.0 → 1.1.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/README.md CHANGED
@@ -1,7 +1,722 @@
1
- # verdaccio-security-filter
1
+ # Verdaccio Security Filter Plugin
2
2
 
3
- **⚠️ This package is currently a placeholder reservation.**
3
+ Advanced security filter plugin for Verdaccio with **dual-layer protection architecture** combining middleware interception and metadata filtering for comprehensive package security.
4
4
 
5
- The full implementation is under development. Please check back soon.
5
+ [![npm version](https://img.shields.io/npm/v/verdaccio-security-filter.svg)](https://www.npmjs.com/package/verdaccio-security-filter)
6
+ [![npm downloads](https://img.shields.io/npm/dm/verdaccio-security-filter.svg)](https://www.npmjs.com/package/verdaccio-security-filter)
7
+ [![CI](https://github.com/ponomarenko/verdaccio-security-filter/actions/workflows/ci.yml/badge.svg)](https://github.com/ponomarenko/verdaccio-security-filter/actions/workflows/ci.yml)
8
+ [![Tests](https://img.shields.io/badge/tests-71%20passing-brightgreen)](./tests)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)]()
10
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen)]()
11
+ [![Verdaccio](https://img.shields.io/badge/Verdaccio-6.x%20%7C%207.x-orange)]()
6
12
 
7
- For updates, see: https://github.com/ponomarenko/verdaccio-security-filter
13
+ ## 🏗️ Dual-Layer Architecture
14
+
15
+ This plugin implements **two independent security layers** for complete protection:
16
+
17
+ ### Layer 1: Middleware (Always Active)
18
+ - ✅ **Whitelist/Blacklist filtering** - Control allowed packages
19
+ - ✅ **Pattern-based blocking** - Block by regex patterns
20
+ - ✅ **Scope control** - Filter by npm scopes
21
+ - ✅ **Tarball interception** - Block downloads even if metadata cached
22
+ - ✅ **Version blocking** - Block specific versions/ranges
23
+
24
+ ### Layer 2: Filter Metadata (Deep Inspection)
25
+ - ✅ **CVE vulnerability scanning** - OSV API integration
26
+ - ✅ **License compliance** - SPDX validation
27
+ - ✅ **Package age verification** - Block newly created packages
28
+ - ✅ **Full metadata access** - Deep package inspection
29
+
30
+ > **Why two layers?** Middleware catches everything at HTTP level, while filter_metadata provides deep inspection when metadata is available. See [DUAL-LAYER-ARCHITECTURE.md](./DUAL-LAYER-ARCHITECTURE.md) for details.
31
+
32
+ ## 🚀 Features
33
+
34
+ ### ✅ Implemented Features
35
+
36
+ #### 🔒 Version Management
37
+ - **Version Range Blocking** - Block vulnerable versions using semver ranges
38
+ - **Block Strategy**: Completely remove versions from registry
39
+ - **Fallback Strategy**: Transparently redirect to safe versions
40
+ - **Exact Version Blocking** - Block specific package@version combinations
41
+ - **Semver Support** - Full semver syntax (`^`, `~`, `>`, `>=`, `<`, `<=`, `x`, `*`)
42
+
43
+ #### 🛡️ CVE & Vulnerability Scanning
44
+ - **OSV Database Integration** - Automatic vulnerability scanning via [OSV API](https://osv.dev/)
45
+ - **Severity Filtering** - Filter by severity: `low`, `medium`, `high`, `critical`
46
+ - **Auto-Block Vulnerable Packages** - Automatically block packages with known CVEs
47
+ - **Caching System** - Configurable cache with update intervals
48
+ - **Multiple Database Support** - Ready for OSV, Snyk, GitHub Advisory
49
+
50
+ #### ⚖️ License Compliance
51
+ - **License Filtering** - Enforce license policies with allowed/blocked lists
52
+ - **SPDX Expression Support** - Parse complex license expressions (OR/AND operators)
53
+ - **Require License** - Option to block packages without license information
54
+ - **Pre-defined Lists** - Common open-source and copyleft license collections
55
+
56
+ #### 🔐 Access Control
57
+ - **Whitelist Mode** - Only explicitly approved packages allowed
58
+ - **Pattern-based Whitelisting** - Regex patterns for package approval
59
+ - **Version Constraints** - Lock approved packages to specific version ranges
60
+ - **Scope Control** - Whitelist/blacklist package scopes (@scope/package)
61
+
62
+ #### 📊 Monitoring & Observability
63
+ - **Enhanced Logging** - Configurable log levels (`debug`, `info`, `warn`, `error`)
64
+ - **Metrics Collection** - Track security events (blocks, fallbacks, CVEs, license violations)
65
+ - **Security Audit Trail** - Detailed logging of all security decisions
66
+ - **Customizable Output** - Log to stdout or file in JSON format
67
+
68
+ #### 🔍 Additional Security
69
+ - **Pattern-based Blocking** - Block suspicious packages by name patterns (regex)
70
+ - **Package Age Filtering** - Block packages or versions that are too new (protect against newly published malicious packages)
71
+ - **Minimum Package Age** - Require packages to exist for a minimum number of days
72
+ - **Minimum Version Age** - Require specific versions to exist for a minimum number of days
73
+ - **Warn-Only Mode** - Log warnings without blocking
74
+ - **Middleware Interception** - HTTP middleware that blocks tarball downloads for blocked packages
75
+ - Prevents blocked packages from being installed as dependencies
76
+ - Intercepts requests to `/:package/-/:filename.tgz` routes
77
+ - Returns 403 Forbidden with detailed error messages
78
+ - **Size Limits** - Enforce minimum and maximum package sizes
79
+ - **Metadata Validation** - Verify package integrity and detect dangerous characters
80
+ - **Checksum Enforcement** - Ensure package integrity
81
+
82
+ #### ⚙️ Reliability & Error Handling
83
+ - **Fail-Safe/Fail-Closed Configuration** - Choose error handling strategy
84
+ - **Fail-Open (Default)** - Allow packages on errors (availability priority)
85
+ - **Fail-Closed** - Block packages on errors (security priority)
86
+ - **Granular Control** - Different strategies for filter, CVE, and license checks
87
+ - **Retry Logic** - Automatic retry with exponential backoff for API calls
88
+ - 3 retries with increasing delays (1s, 2s, 4s)
89
+ - Rate limiting detection and handling
90
+ - Request timeout protection (10s)
91
+ - **Resilient CVE Scanning** - Production-ready vulnerability checking
92
+ - Network failure recovery
93
+ - API timeout protection
94
+ - Graceful degradation on errors
95
+
96
+ ### 🔮 Planned Features (Roadmap)
97
+
98
+ #### Phase 3: Advanced Security
99
+ - [ ] **Dependency Depth Limiting** - Limit dependency tree depth and total count
100
+ - [ ] **Circular Dependency Detection** - Block packages with circular dependencies
101
+ - [ ] **Rate Limiting** - Detect and block suspicious download patterns
102
+ - [ ] **Typosquatting Detection** - AI-powered detection of similar package names
103
+ - [ ] **Package Signing Verification** - PGP signature validation
104
+ - [ ] **Custom Validation Scripts** - Execute custom security checks
105
+
106
+ #### Phase 4: Enterprise Features
107
+ - [ ] **Integration with Security Scanners** - npm audit, Snyk API, Sonatype
108
+ - [ ] **Webhook Notifications** - Real-time alerts for security events
109
+ - [ ] **Web Dashboard** - Visual interface for security analytics
110
+ - [ ] **Email/Slack Notifications** - Alert channels for critical events
111
+ - [ ] **Audit Reports** - Generate compliance reports (PDF, CSV, JSON)
112
+ - [ ] **Multi-Registry Support** - Fallback to other registries
113
+ - [ ] **ML-based Anomaly Detection** - Machine learning for threat detection
114
+
115
+ #### Phase 5: Developer Experience
116
+ - [ ] **Dry Run Mode** - Test rules without actually blocking
117
+ - [ ] **Auto-approve Criteria** - Automatic approval based on npm stats (downloads, stars)
118
+ - [ ] **CLI Tool** - Command-line interface for rule management
119
+ - [ ] **Visual Studio Code Extension** - IDE integration
120
+ - [ ] **GitHub Action** - CI/CD integration
121
+
122
+ ## 📦 Installation
123
+
124
+ ### Prerequisites
125
+
126
+ - Node.js >= 22.0.0
127
+ - Verdaccio >= 5.0.0
128
+
129
+ ```bash
130
+ npm install -g verdaccio
131
+ ```
132
+
133
+ ### Install Plugin
134
+
135
+ ```bash
136
+ # Install from npm (when published)
137
+ npm install -g verdaccio-security-filter
138
+
139
+ # Or install locally for development
140
+ git clone https://github.com/ponomarenko/verdaccio-security-filter.git
141
+ cd verdaccio-security-filter
142
+ npm install
143
+ npm run build
144
+ npm link
145
+ ```
146
+
147
+ ## 🔧 How It Works
148
+
149
+ This plugin implements **two layers of protection** to block malicious packages:
150
+
151
+ ### Layer 1: Metadata Filtering (`filter_metadata`)
152
+ When a client requests package information (e.g., `npm info lodash`), the plugin:
153
+ 1. Checks if the package is allowed (whitelist mode)
154
+ 2. Validates against blocked patterns, scopes, and age requirements
155
+ 3. **Throws HTTP 404 error** for completely blocked packages (patterns, scopes, whitelist violations)
156
+ 4. Filters out specific blocked versions from the versions list for partial blocks
157
+
158
+ **Result**: Blocked packages return "404 Not Found" - as if they don't exist in the registry.
159
+
160
+ ### Layer 2: Middleware Interception (`register_middlewares`)
161
+ When a client tries to download a tarball file (e.g., during `npm install`), the plugin:
162
+ 1. Intercepts **all HTTP requests** early in the middleware chain
163
+ 2. Extracts package name and version from the request URL
164
+ 3. Applies all security checks (whitelist, patterns, scopes, blocked versions, range rules)
165
+ 4. Returns **403 Forbidden** for blocked packages with detailed error message
166
+
167
+ **Result**: Even if metadata is cached, tarball downloads are blocked at the HTTP level.
168
+
169
+ ### Why Both Layers?
170
+
171
+ - **Metadata filtering (404)** - Makes blocked packages invisible to npm/yarn
172
+ - **Middleware interception (403)** - Blocks tarball downloads even with cached metadata
173
+ - Together, they provide **complete protection** against blocked packages being installed in any way
174
+
175
+ Example flow when a blocked package is requested:
176
+ ```
177
+ npm install hawk
178
+ → GET /hawk (metadata request)
179
+ → [Security Filter] Blocked hawk@* - Package is not in whitelist
180
+ → HTTP 404 Not Found: Package blocked by security filter: Not in whitelist
181
+ → npm ERR! 404 Not Found - GET http://localhost:4873/hawk
182
+
183
+ npm install (with hawk as dependency)
184
+ → GET /hawk/-/hawk-9.0.1.tgz (tarball request)
185
+ → [Middleware] Tarball request: hawk/hawk-9.0.1.tgz
186
+ → [Security Filter] Blocked hawk@9.0.1 - Package is not in whitelist
187
+ → HTTP 403 Forbidden: {"error": "Package blocked by security filter", "reason": "Package is not in whitelist"}
188
+ ```
189
+
190
+ ## ⚙️ Configuration
191
+
192
+ ### Quick Start (Middleware Only)
193
+
194
+ Minimal configuration using only Layer 1 (Middleware):
195
+
196
+ ```yaml
197
+ middlewares:
198
+ security-filter:
199
+ enabled: true
200
+ mode: whitelist
201
+ whitelist:
202
+ packages:
203
+ - lodash
204
+ - express
205
+ patterns:
206
+ - "^@types/.*"
207
+ ```
208
+
209
+ ### Full Protection (Dual-Layer)
210
+
211
+ **Recommended:** Use both layers for maximum security:
212
+
213
+ ```yaml
214
+ # Enable filter_metadata (Layer 2)
215
+ packages:
216
+ '@*/*':
217
+ access: $all
218
+ publish: $authenticated
219
+ proxy: npmjs
220
+ storage: security-filter # Enable Layer 2!
221
+
222
+ '**':
223
+ access: $all
224
+ publish: $authenticated
225
+ proxy: npmjs
226
+ storage: security-filter # Enable Layer 2!
227
+
228
+ # Configure security filter
229
+ middlewares:
230
+ security-filter:
231
+ enabled: true
232
+
233
+ # Layer 1: Basic filtering (Middleware)
234
+ mode: whitelist
235
+ whitelist:
236
+ packages: [lodash, express]
237
+ patterns: ["^@types/.*"]
238
+
239
+ blockedVersions:
240
+ - "lodash@4.17.20"
241
+
242
+ # Layer 2: Deep inspection (filter_metadata)
243
+ cveCheck:
244
+ enabled: true
245
+ autoBlock: true
246
+ severity: [critical, high]
247
+
248
+ licenses:
249
+ allowed: [MIT, Apache-2.0, BSD-3-Clause]
250
+
251
+ packageAge:
252
+ enabled: true
253
+ minPackageAgeDays: 7
254
+ ```
255
+
256
+ ### Advanced Configuration with CVE Scanning
257
+
258
+ ```yaml
259
+ # Layer 1: Metadata filtering
260
+ filters:
261
+ security-filter:
262
+ enabled: true
263
+
264
+ # CVE vulnerability scanning
265
+ cveCheck:
266
+ enabled: true
267
+ databases:
268
+ - osv
269
+ - github
270
+ severity:
271
+ - high
272
+ - critical
273
+ autoBlock: true
274
+ updateInterval: 24 # hours
275
+ cacheDir: ./.security-cache
276
+
277
+ # License compliance
278
+ licenses:
279
+ allowed:
280
+ - MIT
281
+ - Apache-2.0
282
+ - BSD-3-Clause
283
+ blocked:
284
+ - GPL-3.0
285
+ - AGPL-3.0
286
+ requireLicense: true
287
+
288
+ # Package age filtering
289
+ packageAge:
290
+ enabled: true
291
+ minPackageAgeDays: 7 # Packages must be at least 7 days old
292
+ minVersionAgeDays: 3 # Versions must be at least 3 days old
293
+ warnOnly: false # Block instead of just warning
294
+
295
+ # Version range rules
296
+ versionRangeRules:
297
+ - package: lodash
298
+ range: "<4.17.21"
299
+ strategy: fallback
300
+ fallbackVersion: "4.17.21"
301
+ reason: "CVE-2021-23337: Command injection"
302
+
303
+ - package: minimist
304
+ range: "<1.2.6"
305
+ strategy: block
306
+ reason: "CVE-2021-44906: Prototype pollution"
307
+
308
+ # Layer 2: Middleware interception
309
+ middlewares:
310
+ security-filter:
311
+ enabled: true
312
+ ```
313
+
314
+ ### Enterprise Whitelist Mode
315
+
316
+ ```yaml
317
+ # Layer 1: Metadata filtering
318
+ filters:
319
+ security-filter:
320
+ enabled: true
321
+
322
+ # Only approved packages allowed
323
+ mode: whitelist
324
+
325
+ whitelist:
326
+ packages:
327
+ - lodash
328
+ - express
329
+ - react
330
+ patterns:
331
+ - "^@mycompany/.*"
332
+ - "^@types/.*"
333
+ versions:
334
+ lodash: "^4.17.21"
335
+ express: "^4.18.0"
336
+
337
+ # Enhanced logging
338
+ logger:
339
+ level: info
340
+ enabled: true
341
+ includeTimestamp: true
342
+
343
+ # Metrics for analytics
344
+ metrics:
345
+ enabled: true
346
+ output: file
347
+ filePath: ./security-metrics.json
348
+
349
+ # Layer 2: Middleware interception
350
+ middlewares:
351
+ security-filter:
352
+ enabled: true
353
+ ```
354
+
355
+ ### High Security Configuration
356
+
357
+ ```yaml
358
+ # Layer 1: Metadata filtering
359
+ filters:
360
+ security-filter:
361
+ enabled: true
362
+ mode: whitelist
363
+
364
+ whitelist:
365
+ packages:
366
+ - lodash
367
+ - axios
368
+ versions:
369
+ lodash: "4.17.21" # Lock to exact version
370
+ axios: "1.6.0"
371
+
372
+ cveCheck:
373
+ enabled: true
374
+ databases: [osv, github, snyk]
375
+ severity: [low, medium, high, critical] # Block ALL
376
+ autoBlock: true
377
+ updateInterval: 6 # Check every 6 hours
378
+
379
+ licenses:
380
+ allowed: [MIT, Apache-2.0, BSD-3-Clause]
381
+ blocked: [GPL-3.0, AGPL-3.0, LGPL-3.0]
382
+ requireLicense: true
383
+
384
+ minPackageSize: 10000 # 10KB minimum
385
+ maxPackageSize: 10485760 # 10MB maximum
386
+
387
+ logger:
388
+ level: debug # Log everything
389
+ enabled: true
390
+ includeTimestamp: true
391
+
392
+ metrics:
393
+ enabled: true
394
+ output: file
395
+ filePath: /var/log/verdaccio/security-metrics.jsonl
396
+
397
+ # Layer 2: Middleware interception
398
+ middlewares:
399
+ security-filter:
400
+ enabled: true
401
+ ```
402
+
403
+ ## 📚 Configuration Reference
404
+
405
+ ### Main Options
406
+
407
+ | Option | Type | Default | Description |
408
+ |--------|------|---------|-------------|
409
+ | `mode` | `string` | `blacklist` | Filter mode: `blacklist` or `whitelist` |
410
+ | `blockedVersions` | `string[]` | `[]` | List of `package@version` to block |
411
+ | `blockedPatterns` | `string[]` | `[]` | Regex patterns for package names |
412
+ | `allowedScopes` | `string[]` | `[]` | Allowed package scopes |
413
+ | `blockedScopes` | `string[]` | `[]` | Blocked package scopes |
414
+ | `minPackageSize` | `number` | `0` | Minimum package size in bytes |
415
+ | `maxPackageSize` | `number` | `104857600` | Maximum package size (100MB) |
416
+ | `enforceChecksum` | `boolean` | `true` | Enforce checksum validation |
417
+
418
+ ### CVE Check Options
419
+
420
+ | Option | Type | Default | Description |
421
+ |--------|------|---------|-------------|
422
+ | `cveCheck.enabled` | `boolean` | `false` | Enable CVE scanning |
423
+ | `cveCheck.databases` | `string[]` | `['osv']` | Databases: `osv`, `snyk`, `github` |
424
+ | `cveCheck.severity` | `string[]` | `['high', 'critical']` | Severity levels to check |
425
+ | `cveCheck.autoBlock` | `boolean` | `false` | Auto-block vulnerable packages |
426
+ | `cveCheck.updateInterval` | `number` | `24` | Cache update interval (hours) |
427
+ | `cveCheck.cacheDir` | `string` | `./.security-cache` | Cache directory path |
428
+
429
+ ### License Options
430
+
431
+ | Option | Type | Default | Description |
432
+ |--------|------|---------|-------------|
433
+ | `licenses.allowed` | `string[]` | `[]` | Allowed license list |
434
+ | `licenses.blocked` | `string[]` | `[]` | Blocked license list |
435
+ | `licenses.requireLicense` | `boolean` | `false` | Require license field |
436
+
437
+ ### Whitelist Options
438
+
439
+ | Option | Type | Default | Description |
440
+ |--------|------|---------|-------------|
441
+ | `whitelist.packages` | `string[]` | `[]` | Approved package names |
442
+ | `whitelist.patterns` | `string[]` | `[]` | Regex patterns for approval |
443
+ | `whitelist.versions` | `object` | `{}` | Version constraints per package |
444
+
445
+ ### Logger Options
446
+
447
+ | Option | Type | Default | Description |
448
+ |--------|------|---------|-------------|
449
+ | `logger.level` | `string` | `info` | Log level: `debug`, `info`, `warn`, `error` |
450
+ | `logger.enabled` | `boolean` | `true` | Enable logging |
451
+ | `logger.includeTimestamp` | `boolean` | `false` | Include timestamps in logs |
452
+
453
+ ### Metrics Options
454
+
455
+ | Option | Type | Default | Description |
456
+ |--------|------|---------|-------------|
457
+ | `metrics.enabled` | `boolean` | `false` | Enable metrics collection |
458
+ | `metrics.output` | `string` | `stdout` | Output: `stdout` or `file` |
459
+ | `metrics.filePath` | `string` | `./security-metrics.json` | Metrics file path |
460
+
461
+ ### Package Age Options
462
+
463
+ | Option | Type | Default | Description |
464
+ |--------|------|---------|-------------|
465
+ | `packageAge.enabled` | `boolean` | `false` | Enable package age filtering |
466
+ | `packageAge.minPackageAgeDays` | `number` | `0` | Minimum age for packages (days) |
467
+ | `packageAge.minVersionAgeDays` | `number` | `undefined` | Minimum age for versions (days) |
468
+ | `packageAge.warnOnly` | `boolean` | `false` | Only warn, don't block |
469
+
470
+ ### Error Handling Options
471
+
472
+ | Option | Type | Default | Description |
473
+ |--------|------|---------|-------------|
474
+ | `errorHandling.onFilterError` | `'fail-open' \| 'fail-closed'` | `'fail-open'` | Strategy when filter errors occur |
475
+ | `errorHandling.onCveCheckError` | `'fail-open' \| 'fail-closed'` | `'fail-open'` | Strategy when CVE check fails |
476
+ | `errorHandling.onLicenseCheckError` | `'fail-open' \| 'fail-closed'` | `'fail-open'` | Strategy when license check fails |
477
+
478
+ **Error Handling Strategies:**
479
+ - **fail-open** (Default): Allow packages through on errors (prioritizes availability)
480
+ - **fail-closed**: Block packages on errors (prioritizes security)
481
+
482
+ **Example Configuration:**
483
+ ```yaml
484
+ # Production: Security-first approach
485
+ errorHandling:
486
+ onFilterError: fail-closed
487
+ onCveCheckError: fail-closed
488
+ onLicenseCheckError: fail-closed
489
+
490
+ # Development: Availability-first approach
491
+ errorHandling:
492
+ onFilterError: fail-open
493
+ onCveCheckError: fail-open
494
+ onLicenseCheckError: fail-open
495
+
496
+ # Balanced: Block only on license failures
497
+ errorHandling:
498
+ onFilterError: fail-open
499
+ onCveCheckError: fail-open
500
+ onLicenseCheckError: fail-closed
501
+ ```
502
+
503
+ ### Version Range Rules
504
+
505
+ ```typescript
506
+ {
507
+ package: string; // Package name
508
+ range: string; // Semver range
509
+ strategy: 'block' | 'fallback';
510
+ fallbackVersion?: string; // Required for fallback strategy
511
+ reason?: string; // Explanation for blocking
512
+ }
513
+ ```
514
+
515
+ ## 📖 Examples
516
+
517
+ See the [examples](./examples) directory for complete configuration examples:
518
+ - [basic.yaml](./examples/basic.yaml) - Simple setup for small teams
519
+ - [enterprise.yaml](./examples/enterprise.yaml) - Comprehensive security setup
520
+ - [high-security.yaml](./examples/high-security.yaml) - Maximum security configuration
521
+
522
+ ## 🧪 Testing
523
+
524
+ ```bash
525
+ # Run all tests
526
+ npm test
527
+
528
+ # Run tests with coverage
529
+ npm test:coverage
530
+
531
+ # Run tests in watch mode
532
+ npm test:watch
533
+ ```
534
+
535
+ **Test Results:**
536
+ - ✅ 80 tests passing
537
+ - ✅ 60%+ code coverage
538
+ - ✅ SecurityFilterPlugin: 21 tests
539
+ - ✅ PackageAgeChecker: 13 tests
540
+ - ✅ SecurityLogger: 16 tests
541
+ - ✅ LicenseChecker: 15 tests
542
+ - ✅ WhitelistChecker: 15 tests
543
+
544
+ ## 🔧 Development
545
+
546
+ ```bash
547
+ # Install dependencies
548
+ npm install
549
+
550
+ # Build
551
+ npm run build
552
+
553
+ # Lint
554
+ npm run lint
555
+
556
+ # Watch mode for development
557
+ npm run build -- --watch
558
+ ```
559
+
560
+ ## 📊 Metrics & Monitoring
561
+
562
+ When metrics are enabled, the plugin tracks:
563
+
564
+ - `block` - Packages blocked by version/pattern/scope rules
565
+ - `fallback` - Versions redirected to safe alternatives
566
+ - `publish_rejected` - Publish attempts rejected
567
+ - `cve_detected` - CVE vulnerabilities found
568
+ - `license_blocked` - Packages blocked by license rules
569
+ - `package_too_new` - Packages/versions blocked due to age restrictions
570
+
571
+ Example metrics output:
572
+ ```json
573
+ {
574
+ "timestamp": "2025-01-15T10:30:00.000Z",
575
+ "event": "cve_detected",
576
+ "packageName": "lodash",
577
+ "version": "4.17.20",
578
+ "reason": "CVE-2021-23337 (high)",
579
+ "metadata": {
580
+ "cveId": "CVE-2021-23337",
581
+ "severity": "high"
582
+ }
583
+ }
584
+ ```
585
+
586
+ ## 🛠️ Use Cases
587
+
588
+ ### 1. Block Known Vulnerabilities
589
+
590
+ ```yaml
591
+ versionRangeRules:
592
+ - package: lodash
593
+ range: ">=4.17.0 <4.17.21"
594
+ strategy: block
595
+ reason: "CVE-2021-23337: Command injection vulnerability"
596
+ ```
597
+
598
+ ### 2. Transparent Security Patches (Fallback)
599
+
600
+ ```yaml
601
+ versionRangeRules:
602
+ - package: axios
603
+ range: "0.21.1"
604
+ strategy: fallback
605
+ fallbackVersion: "0.21.4"
606
+ reason: "SSRF vulnerability fix"
607
+ ```
608
+
609
+ ### 3. Enforce Corporate License Policy
610
+
611
+ ```yaml
612
+ licenses:
613
+ allowed:
614
+ - MIT
615
+ - Apache-2.0
616
+ - BSD-3-Clause
617
+ blocked:
618
+ - GPL-3.0
619
+ - AGPL-3.0
620
+ requireLicense: true
621
+ ```
622
+
623
+ ### 4. Whitelist Only Approved Packages
624
+
625
+ ```yaml
626
+ mode: whitelist
627
+ whitelist:
628
+ packages:
629
+ - lodash
630
+ - express
631
+ patterns:
632
+ - "^@mycompany/.*"
633
+ versions:
634
+ lodash: "^4.17.21"
635
+ ```
636
+
637
+ ### 5. Automatic CVE Scanning
638
+
639
+ ```yaml
640
+ cveCheck:
641
+ enabled: true
642
+ databases: [osv, github]
643
+ severity: [high, critical]
644
+ autoBlock: true
645
+ updateInterval: 12
646
+ ```
647
+
648
+ ### 6. Block Recently Published Packages
649
+
650
+ ```yaml
651
+ # Protect against newly published malicious packages
652
+ packageAge:
653
+ enabled: true
654
+ minPackageAgeDays: 7 # Package must exist for 7 days
655
+ minVersionAgeDays: 3 # Version must exist for 3 days
656
+ warnOnly: false # Block, don't just warn
657
+ ```
658
+
659
+ ## 🔐 Security Best Practices
660
+
661
+ 1. **Enable CVE Scanning** - Automatically detect and block vulnerable packages
662
+ 2. **Use Whitelist Mode** - For maximum security in sensitive environments
663
+ 3. **Enforce License Compliance** - Prevent legal issues with license filtering
664
+ 4. **Enable Package Age Filtering** - Block newly published packages to prevent supply chain attacks
665
+ 5. **Enable Metrics** - Track security events for audit and compliance
666
+ 6. **Regular Updates** - Keep the plugin and CVE database cache updated
667
+ 7. **Test Rules** - Use dry run mode (planned) before applying strict rules
668
+ 8. **Monitor Logs** - Review security logs regularly for suspicious activity
669
+
670
+ ## 🐛 Troubleshooting
671
+
672
+ ### Plugin not loading
673
+ - Verify Verdaccio version >= 5.0.0
674
+ - Check plugin is listed in `config.yaml` under `filters`
675
+ - Ensure plugin is installed globally or linked correctly
676
+
677
+ ### CVE scanning not working
678
+ - Check internet connectivity to OSV API (https://api.osv.dev)
679
+ - Verify `cveCheck.enabled` is `true`
680
+ - Check cache directory permissions
681
+ - Review logs for API errors
682
+
683
+ ### Tests failing
684
+ - Ensure Node.js >= 22.0.0
685
+ - Run `npm install` to update dependencies
686
+ - Clear Jest cache: `npx jest --clearCache`
687
+
688
+ ### Package blocked unexpectedly
689
+ - Check logs for the reason: `logger.level: debug`
690
+ - Review all active rules (patterns, scopes, CVE, license)
691
+ - In whitelist mode, ensure package is explicitly approved
692
+
693
+ ## 📄 License
694
+
695
+ MIT © [Vitaliy Ponomarenko](https://github.com/ponomarenko)
696
+
697
+ ## 🤝 Contributing
698
+
699
+ Contributions are welcome! Please feel free to submit a Pull Request.
700
+
701
+ 1. Fork the repository
702
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
703
+ 3. Run tests (`npm test`)
704
+ 4. Commit your changes (`git commit -m 'Add amazing feature'`)
705
+ 5. Push to the branch (`git push origin feature/amazing-feature`)
706
+ 6. Open a Pull Request
707
+
708
+ ## 📞 Support
709
+
710
+ - **Issues**: [GitHub Issues](https://github.com/ponomarenko/verdaccio-security-filter/issues)
711
+ - **Documentation**: [README](./README.md)
712
+ - **Examples**: [Configuration Examples](./examples)
713
+
714
+ ## 🙏 Acknowledgments
715
+
716
+ - [Verdaccio](https://verdaccio.org/) - The awesome private npm registry
717
+ - [OSV](https://osv.dev/) - Open Source Vulnerabilities database
718
+ - All contributors and users of this plugin
719
+
720
+ ---
721
+
722
+ **Made with ❤️ for the npm security community**