verdaccio-security-filter 1.0.6

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