{"id":35218879,"url":"https://github.com/ponomarenko/verdaccio-security-filter","last_synced_at":"2026-03-27T04:31:14.964Z","repository":{"id":326673101,"uuid":"1105439169","full_name":"ponomarenko/verdaccio-security-filter","owner":"ponomarenko","description":"Advanced security filter plugin for Verdaccio with version range blocking and fallback strategies","archived":false,"fork":false,"pushed_at":"2026-02-18T16:58:33.000Z","size":697,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-18T18:50:45.424Z","etag":null,"topics":["security","verdaccio","verdaccio-plugin","vulnerability"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ponomarenko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-27T15:57:32.000Z","updated_at":"2026-02-18T16:58:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ponomarenko/verdaccio-security-filter","commit_stats":null,"previous_names":["ponomarenko/verdaccio-security-filter"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/ponomarenko/verdaccio-security-filter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ponomarenko%2Fverdaccio-security-filter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ponomarenko%2Fverdaccio-security-filter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ponomarenko%2Fverdaccio-security-filter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ponomarenko%2Fverdaccio-security-filter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ponomarenko","download_url":"https://codeload.github.com/ponomarenko/verdaccio-security-filter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ponomarenko%2Fverdaccio-security-filter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31019347,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T03:51:26.850Z","status":"ssl_error","status_checked_at":"2026-03-27T03:51:09.693Z","response_time":164,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["security","verdaccio","verdaccio-plugin","vulnerability"],"created_at":"2025-12-29T23:31:15.383Z","updated_at":"2026-03-27T04:31:14.955Z","avatar_url":"https://github.com/ponomarenko.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Verdaccio Security Filter Plugin\n\nAdvanced security filter plugin for Verdaccio with **dual-layer protection architecture** combining middleware interception and metadata filtering for comprehensive package security.\n\n[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)\n[![npm version](https://img.shields.io/npm/v/verdaccio-security-filter.svg)](https://www.npmjs.com/package/verdaccio-security-filter)\n[![npm downloads](https://img.shields.io/npm/dm/verdaccio-security-filter.svg)](https://www.npmjs.com/package/verdaccio-security-filter)\n[![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)\n[![Tests](https://img.shields.io/badge/tests-71%20passing-brightgreen)](./tests)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)]()\n[![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen)]()\n[![Verdaccio](https://img.shields.io/badge/Verdaccio-6.x%20%7C%207.x-orange)]()\n\n## 🏗️ Dual-Layer Architecture\n\nThis plugin implements **two independent security layers** for complete protection:\n\n### Layer 1: Middleware (Always Active)\n- ✅ **Whitelist/Blacklist filtering** - Control allowed packages\n- ✅ **Pattern-based blocking** - Block by regex patterns\n- ✅ **Scope control** - Filter by npm scopes\n- ✅ **Tarball interception** - Block downloads even if metadata cached\n- ✅ **Version blocking** - Block specific versions/ranges\n\n### Layer 2: Filter Metadata (Deep Inspection)\n- ✅ **CVE vulnerability scanning** - OSV API integration\n- ✅ **License compliance** - SPDX validation\n- ✅ **Package age verification** - Block newly created packages\n- ✅ **Full metadata access** - Deep package inspection\n\n\u003e **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.\n\n## 🚀 Features\n\n### ✅ Implemented Features\n\n#### 🔒 Version Management\n- **Version Range Blocking** - Block vulnerable versions using semver ranges\n  - **Block Strategy**: Completely remove versions from registry\n  - **Fallback Strategy**: Transparently redirect to safe versions\n- **Exact Version Blocking** - Block specific package@version combinations\n- **Semver Support** - Full semver syntax (`^`, `~`, `\u003e`, `\u003e=`, `\u003c`, `\u003c=`, `x`, `*`)\n\n#### 🛡️ CVE \u0026 Vulnerability Scanning\n- **OSV Database Integration** - Automatic vulnerability scanning via [OSV API](https://osv.dev/)\n- **Severity Filtering** - Filter by severity: `low`, `medium`, `high`, `critical`\n- **Auto-Block Vulnerable Packages** - Automatically block packages with known CVEs\n- **Caching System** - Configurable cache with update intervals\n- **Multiple Database Support** - Ready for OSV, Snyk, GitHub Advisory\n\n#### ⚖️ License Compliance\n- **License Filtering** - Enforce license policies with allowed/blocked lists\n- **SPDX Expression Support** - Parse complex license expressions (OR/AND operators)\n- **Require License** - Option to block packages without license information\n- **Pre-defined Lists** - Common open-source and copyleft license collections\n\n#### 🔐 Access Control\n- **Whitelist Mode** - Only explicitly approved packages allowed\n- **Pattern-based Whitelisting** - Regex patterns for package approval\n- **Version Constraints** - Lock approved packages to specific version ranges\n- **Scope Control** - Whitelist/blacklist package scopes (@scope/package)\n\n#### 📊 Monitoring \u0026 Observability\n- **Enhanced Logging** - Configurable log levels (`debug`, `info`, `warn`, `error`)\n- **Metrics Collection** - Track security events (blocks, fallbacks, CVEs, license violations)\n- **Security Audit Trail** - Detailed logging of all security decisions\n- **Customizable Output** - Log to stdout or file in JSON format\n\n#### 🔍 Additional Security\n- **Pattern-based Blocking** - Block suspicious packages by name patterns (regex)\n- **Package Age Filtering** - Block packages or versions that are too new (protect against newly published malicious packages)\n  - **Minimum Package Age** - Require packages to exist for a minimum number of days\n  - **Minimum Version Age** - Require specific versions to exist for a minimum number of days\n  - **Warn-Only Mode** - Log warnings without blocking\n- **Author Filtering** - Block packages based on author information\n  - **Block by Author Name** - Block specific author names or patterns\n  - **Block by Email** - Block specific email addresses or patterns\n  - **Block by Email Domain** - Block entire email domains (e.g., `.ru`, `yandex.ru`)\n  - **Block by Region** - Block authors from specific regions based on email domains\n  - **Maintainer \u0026 Contributor Checking** - Validates all package maintainers and contributors\n  - **Warn-Only Mode** - Log warnings without blocking\n- **Middleware Interception** - HTTP middleware that blocks tarball downloads for blocked packages\n  - Prevents blocked packages from being installed as dependencies\n  - Intercepts requests to `/:package/-/:filename.tgz` routes\n  - Returns 403 Forbidden with detailed error messages\n- **Size Limits** - Enforce minimum and maximum package sizes\n- **Metadata Validation** - Verify package integrity and detect dangerous characters\n- **Checksum Enforcement** - Ensure package integrity\n\n#### ⚙️ Reliability \u0026 Error Handling\n- **Fail-Safe/Fail-Closed Configuration** - Choose error handling strategy\n  - **Fail-Open (Default)** - Allow packages on errors (availability priority)\n  - **Fail-Closed** - Block packages on errors (security priority)\n  - **Granular Control** - Different strategies for filter, CVE, and license checks\n- **Retry Logic** - Automatic retry with exponential backoff for API calls\n  - 3 retries with increasing delays (1s, 2s, 4s)\n  - Rate limiting detection and handling\n  - Request timeout protection (10s)\n- **Resilient CVE Scanning** - Production-ready vulnerability checking\n  - Network failure recovery\n  - API timeout protection\n  - Graceful degradation on errors\n\n### 🔮 Planned Features (Roadmap)\n\n#### Phase 3: Advanced Security\n- [ ] **Dependency Depth Limiting** - Limit dependency tree depth and total count\n- [ ] **Circular Dependency Detection** - Block packages with circular dependencies\n- [ ] **Rate Limiting** - Detect and block suspicious download patterns\n- [ ] **Typosquatting Detection** - AI-powered detection of similar package names\n- [ ] **Package Signing Verification** - PGP signature validation\n- [ ] **Custom Validation Scripts** - Execute custom security checks\n\n#### Phase 4: Enterprise Features\n- [ ] **Integration with Security Scanners** - npm audit, Snyk API, Sonatype\n- [ ] **Webhook Notifications** - Real-time alerts for security events\n- [ ] **Web Dashboard** - Visual interface for security analytics\n- [ ] **Email/Slack Notifications** - Alert channels for critical events\n- [ ] **Audit Reports** - Generate compliance reports (PDF, CSV, JSON)\n- [ ] **Multi-Registry Support** - Fallback to other registries\n- [ ] **ML-based Anomaly Detection** - Machine learning for threat detection\n\n#### Phase 5: Developer Experience\n- [ ] **Dry Run Mode** - Test rules without actually blocking\n- [ ] **Auto-approve Criteria** - Automatic approval based on npm stats (downloads, stars)\n- [ ] **CLI Tool** - Command-line interface for rule management\n- [ ] **Visual Studio Code Extension** - IDE integration\n- [ ] **GitHub Action** - CI/CD integration\n\n## 📦 Installation\n\n### Prerequisites\n\n- Node.js \u003e= 22.0.0\n- Verdaccio \u003e= 5.0.0\n\n```bash\nnpm install -g verdaccio\n```\n\n### Install Plugin\n\n```bash\n# Install from npm (when published)\nnpm install -g verdaccio-security-filter\n\n# Or install locally for development\ngit clone https://github.com/ponomarenko/verdaccio-security-filter.git\ncd verdaccio-security-filter\nnpm install\nnpm run build\nnpm link\n```\n\n## 🔧 How It Works\n\nThis plugin implements **two layers of protection** to block malicious packages:\n\n### Layer 1: Metadata Filtering (`filter_metadata`)\nWhen a client requests package information (e.g., `npm info lodash`), the plugin:\n1. Checks if the package is allowed (whitelist mode)\n2. Validates against blocked patterns, scopes, and age requirements\n3. **Throws HTTP 404 error** for completely blocked packages (patterns, scopes, whitelist violations)\n4. Filters out specific blocked versions from the versions list for partial blocks\n\n**Result**: Blocked packages return \"404 Not Found\" - as if they don't exist in the registry.\n\n### Layer 2: Middleware Interception (`register_middlewares`)\nWhen a client tries to download a tarball file (e.g., during `npm install`), the plugin:\n1. Intercepts **all HTTP requests** early in the middleware chain\n2. Extracts package name and version from the request URL\n3. Applies all security checks (whitelist, patterns, scopes, blocked versions, range rules)\n4. Returns **403 Forbidden** for blocked packages with detailed error message\n\n**Result**: Even if metadata is cached, tarball downloads are blocked at the HTTP level.\n\n### Why Both Layers?\n\n- **Metadata filtering (404)** - Makes blocked packages invisible to npm/yarn\n- **Middleware interception (403)** - Blocks tarball downloads even with cached metadata\n- Together, they provide **complete protection** against blocked packages being installed in any way\n\nExample flow when a blocked package is requested:\n```\nnpm install hawk\n→ GET /hawk (metadata request)\n→ [Security Filter] Blocked hawk@* - Package is not in whitelist\n→ HTTP 404 Not Found: Package blocked by security filter: Not in whitelist\n→ npm ERR! 404 Not Found - GET http://localhost:4873/hawk\n\nnpm install (with hawk as dependency)\n→ GET /hawk/-/hawk-9.0.1.tgz (tarball request)\n→ [Middleware] Tarball request: hawk/hawk-9.0.1.tgz\n→ [Security Filter] Blocked hawk@9.0.1 - Package is not in whitelist\n→ HTTP 403 Forbidden: {\"error\": \"Package blocked by security filter\", \"reason\": \"Package is not in whitelist\"}\n```\n\n## ⚙️ Configuration\n\n### Quick Start (Middleware Only)\n\nMinimal configuration using only Layer 1 (Middleware):\n\n```yaml\nmiddlewares:\n  security-filter:\n    enabled: true\n    mode: whitelist\n    whitelist:\n      packages:\n        - lodash\n        - express\n      patterns:\n        - \"^@types/.*\"\n```\n\n### Full Protection (Dual-Layer)\n\n**Recommended:** Use both layers for maximum security:\n\n```yaml\n# Enable filter_metadata (Layer 2)\npackages:\n  '@*/*':\n    access: $all\n    publish: $authenticated\n    proxy: npmjs\n    storage: security-filter  # Enable Layer 2!\n\n  '**':\n    access: $all\n    publish: $authenticated\n    proxy: npmjs\n    storage: security-filter  # Enable Layer 2!\n\n# Configure security filter\nmiddlewares:\n  security-filter:\n    enabled: true\n\n    # Layer 1: Basic filtering (Middleware)\n    mode: whitelist\n    whitelist:\n      packages: [lodash, express]\n      patterns: [\"^@types/.*\"]\n\n    blockedVersions:\n      - \"lodash@4.17.20\"\n\n    # Layer 2: Deep inspection (filter_metadata)\n    cveCheck:\n      enabled: true\n      autoBlock: true\n      severity: [critical, high]\n\n    licenses:\n      allowed: [MIT, Apache-2.0, BSD-3-Clause]\n\n    packageAge:\n      enabled: true\n      minPackageAgeDays: 7\n```\n\n### Advanced Configuration with CVE Scanning\n\n```yaml\n# Layer 1: Metadata filtering\nfilters:\n  security-filter:\n    enabled: true\n\n    # CVE vulnerability scanning\n    cveCheck:\n      enabled: true\n      databases:\n        - osv\n        - github\n      severity:\n        - high\n        - critical\n      autoBlock: true\n      updateInterval: 24          # hours\n      cacheDir: ./.security-cache\n\n    # License compliance\n    licenses:\n      allowed:\n        - MIT\n        - Apache-2.0\n        - BSD-3-Clause\n      blocked:\n        - GPL-3.0\n        - AGPL-3.0\n      requireLicense: true\n\n    # Package age filtering\n    packageAge:\n      enabled: true\n      minPackageAgeDays: 7       # Packages must be at least 7 days old\n      minVersionAgeDays: 3       # Versions must be at least 3 days old\n      warnOnly: false            # Block instead of just warning\n\n    # Version range rules\n    versionRangeRules:\n      - package: lodash\n        range: \"\u003c4.17.21\"\n        strategy: fallback\n        fallbackVersion: \"4.17.21\"\n        reason: \"CVE-2021-23337: Command injection\"\n\n      - package: minimist\n        range: \"\u003c1.2.6\"\n        strategy: block\n        reason: \"CVE-2021-44906: Prototype pollution\"\n\n# Layer 2: Middleware interception\nmiddlewares:\n  security-filter:\n    enabled: true\n```\n\n### Enterprise Whitelist Mode\n\n```yaml\n# Layer 1: Metadata filtering\nfilters:\n  security-filter:\n    enabled: true\n\n    # Only approved packages allowed\n    mode: whitelist\n\n    whitelist:\n      packages:\n        - lodash\n        - express\n        - react\n      patterns:\n        - \"^@mycompany/.*\"\n        - \"^@types/.*\"\n      versions:\n        lodash: \"^4.17.21\"\n        express: \"^4.18.0\"\n\n    # Enhanced logging\n    logger:\n      level: info\n      enabled: true\n      includeTimestamp: true\n\n    # Metrics for analytics\n    metrics:\n      enabled: true\n      output: file\n      filePath: ./security-metrics.json\n\n# Layer 2: Middleware interception\nmiddlewares:\n  security-filter:\n    enabled: true\n```\n\n### High Security Configuration\n\n```yaml\n# Layer 1: Metadata filtering\nfilters:\n  security-filter:\n    enabled: true\n    mode: whitelist\n\n    whitelist:\n      packages:\n        - lodash\n        - axios\n      versions:\n        lodash: \"4.17.21\"    # Lock to exact version\n        axios: \"1.6.0\"\n\n    cveCheck:\n      enabled: true\n      databases: [osv, github, snyk]\n      severity: [low, medium, high, critical]  # Block ALL\n      autoBlock: true\n      updateInterval: 6                         # Check every 6 hours\n\n    licenses:\n      allowed: [MIT, Apache-2.0, BSD-3-Clause]\n      blocked: [GPL-3.0, AGPL-3.0, LGPL-3.0]\n      requireLicense: true\n\n    minPackageSize: 10000      # 10KB minimum\n    maxPackageSize: 10485760   # 10MB maximum\n\n    logger:\n      level: debug             # Log everything\n      enabled: true\n      includeTimestamp: true\n\n    metrics:\n      enabled: true\n      output: file\n      filePath: /var/log/verdaccio/security-metrics.jsonl\n\n# Layer 2: Middleware interception\nmiddlewares:\n  security-filter:\n    enabled: true\n```\n\n## 📚 Configuration Reference\n\n### Main Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `mode` | `string` | `blacklist` | Filter mode: `blacklist` or `whitelist` |\n| `blockedVersions` | `string[]` | `[]` | List of `package@version` to block |\n| `blockedPatterns` | `string[]` | `[]` | Regex patterns for package names |\n| `allowedScopes` | `string[]` | `[]` | Allowed package scopes |\n| `blockedScopes` | `string[]` | `[]` | Blocked package scopes |\n| `minPackageSize` | `number` | `0` | Minimum package size in bytes |\n| `maxPackageSize` | `number` | `104857600` | Maximum package size (100MB) |\n| `enforceChecksum` | `boolean` | `true` | Enforce checksum validation |\n\n### CVE Check Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `cveCheck.enabled` | `boolean` | `false` | Enable CVE scanning |\n| `cveCheck.databases` | `string[]` | `['osv']` | Databases: `osv`, `snyk`, `github` |\n| `cveCheck.severity` | `string[]` | `['high', 'critical']` | Severity levels to check |\n| `cveCheck.autoBlock` | `boolean` | `false` | Auto-block vulnerable packages |\n| `cveCheck.updateInterval` | `number` | `24` | Cache update interval (hours) |\n| `cveCheck.cacheDir` | `string` | `./.security-cache` | Cache directory path |\n\n### License Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `licenses.allowed` | `string[]` | `[]` | Allowed license list |\n| `licenses.blocked` | `string[]` | `[]` | Blocked license list |\n| `licenses.requireLicense` | `boolean` | `false` | Require license field |\n\n### Whitelist Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `whitelist.packages` | `string[]` | `[]` | Approved package names |\n| `whitelist.patterns` | `string[]` | `[]` | Regex patterns for approval |\n| `whitelist.versions` | `object` | `{}` | Version constraints per package |\n\n### Logger Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `logger.level` | `string` | `info` | Log level: `debug`, `info`, `warn`, `error` |\n| `logger.enabled` | `boolean` | `true` | Enable logging |\n| `logger.includeTimestamp` | `boolean` | `false` | Include timestamps in logs |\n\n### Metrics Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `metrics.enabled` | `boolean` | `false` | Enable metrics collection |\n| `metrics.output` | `string` | `stdout` | Output: `stdout` or `file` |\n| `metrics.filePath` | `string` | `./security-metrics.json` | Metrics file path |\n\n### Package Age Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `packageAge.enabled` | `boolean` | `false` | Enable package age filtering |\n| `packageAge.minPackageAgeDays` | `number` | `0` | Minimum age for packages (days) |\n| `packageAge.minVersionAgeDays` | `number` | `undefined` | Minimum age for versions (days) |\n| `packageAge.warnOnly` | `boolean` | `false` | Only warn, don't block |\n\n### Author Filter Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `authorFilter.enabled` | `boolean` | `false` | Enable author filtering |\n| `authorFilter.blockedAuthors` | `string[]` | `[]` | List of author names to block |\n| `authorFilter.blockedAuthorPatterns` | `string[]` | `[]` | Regex patterns for author names |\n| `authorFilter.blockedEmails` | `string[]` | `[]` | List of email addresses to block |\n| `authorFilter.blockedEmailPatterns` | `string[]` | `[]` | Regex patterns for author emails |\n| `authorFilter.blockedEmailDomains` | `string[]` | `[]` | Email domains to block (e.g., `.ru`, `yandex.ru`) |\n| `authorFilter.blockedRegions` | `string[]` | `[]` | Region codes to block (`ru`, `cn`, `by`, `kp`, `ir`, `sy`, `cu`, `sd`) |\n| `authorFilter.requireVerifiedEmail` | `boolean` | `false` | Require author email information |\n| `authorFilter.warnOnly` | `boolean` | `false` | Only warn, don't block |\n\n### Error Handling Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `errorHandling.onFilterError` | `'fail-open' \\| 'fail-closed'` | `'fail-open'` | Strategy when filter errors occur |\n| `errorHandling.onCveCheckError` | `'fail-open' \\| 'fail-closed'` | `'fail-open'` | Strategy when CVE check fails |\n| `errorHandling.onLicenseCheckError` | `'fail-open' \\| 'fail-closed'` | `'fail-open'` | Strategy when license check fails |\n\n**Error Handling Strategies:**\n- **fail-open** (Default): Allow packages through on errors (prioritizes availability)\n- **fail-closed**: Block packages on errors (prioritizes security)\n\n**Example Configuration:**\n```yaml\n# Production: Security-first approach\nerrorHandling:\n  onFilterError: fail-closed\n  onCveCheckError: fail-closed\n  onLicenseCheckError: fail-closed\n\n# Development: Availability-first approach\nerrorHandling:\n  onFilterError: fail-open\n  onCveCheckError: fail-open\n  onLicenseCheckError: fail-open\n\n# Balanced: Block only on license failures\nerrorHandling:\n  onFilterError: fail-open\n  onCveCheckError: fail-open\n  onLicenseCheckError: fail-closed\n```\n\n### Version Range Rules\n\n```typescript\n{\n  package: string;           // Package name\n  range: string;             // Semver range\n  strategy: 'block' | 'fallback';\n  fallbackVersion?: string;  // Required for fallback strategy\n  reason?: string;           // Explanation for blocking\n}\n```\n\n## 📖 Examples\n\nSee the [examples](./examples) directory for complete configuration examples:\n- [basic.yaml](./examples/basic.yaml) - Simple setup for small teams\n- [enterprise.yaml](./examples/enterprise.yaml) - Comprehensive security setup\n- [high-security.yaml](./examples/high-security.yaml) - Maximum security configuration\n\n## 🧪 Testing\n\n```bash\n# Run all tests\nnpm test\n\n# Run tests with coverage\nnpm test:coverage\n\n# Run tests in watch mode\nnpm test:watch\n```\n\n**Test Results:**\n- ✅ 108 tests passing\n- ✅ 60%+ code coverage\n- ✅ SecurityFilterPlugin: 21 tests\n- ✅ PackageAgeChecker: 13 tests\n- ✅ SecurityLogger: 16 tests\n- ✅ LicenseChecker: 15 tests\n- ✅ WhitelistChecker: 15 tests\n- ✅ AuthorChecker: 28 tests\n\n## 🔧 Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Lint\nnpm run lint\n\n# Watch mode for development\nnpm run build -- --watch\n```\n\n## 📊 Metrics \u0026 Monitoring\n\nWhen metrics are enabled, the plugin tracks:\n\n- `block` - Packages blocked by version/pattern/scope rules\n- `fallback` - Versions redirected to safe alternatives\n- `publish_rejected` - Publish attempts rejected\n- `cve_detected` - CVE vulnerabilities found\n- `license_blocked` - Packages blocked by license rules\n- `package_too_new` - Packages/versions blocked due to age restrictions\n- `author_blocked` - Packages blocked due to author/region filtering\n\nExample metrics output:\n```json\n{\n  \"timestamp\": \"2025-01-15T10:30:00.000Z\",\n  \"event\": \"cve_detected\",\n  \"packageName\": \"lodash\",\n  \"version\": \"4.17.20\",\n  \"reason\": \"CVE-2021-23337 (high)\",\n  \"metadata\": {\n    \"cveId\": \"CVE-2021-23337\",\n    \"severity\": \"high\"\n  }\n}\n```\n\n## 🛠️ Use Cases\n\n### 1. Block Known Vulnerabilities\n\n```yaml\nversionRangeRules:\n  - package: lodash\n    range: \"\u003e=4.17.0 \u003c4.17.21\"\n    strategy: block\n    reason: \"CVE-2021-23337: Command injection vulnerability\"\n```\n\n### 2. Transparent Security Patches (Fallback)\n\n```yaml\nversionRangeRules:\n  - package: axios\n    range: \"0.21.1\"\n    strategy: fallback\n    fallbackVersion: \"0.21.4\"\n    reason: \"SSRF vulnerability fix\"\n```\n\n### 3. Enforce Corporate License Policy\n\n```yaml\nlicenses:\n  allowed:\n    - MIT\n    - Apache-2.0\n    - BSD-3-Clause\n  blocked:\n    - GPL-3.0\n    - AGPL-3.0\n  requireLicense: true\n```\n\n### 4. Whitelist Only Approved Packages\n\n```yaml\nmode: whitelist\nwhitelist:\n  packages:\n    - lodash\n    - express\n  patterns:\n    - \"^@mycompany/.*\"\n  versions:\n    lodash: \"^4.17.21\"\n```\n\n### 5. Automatic CVE Scanning\n\n```yaml\ncveCheck:\n  enabled: true\n  databases: [osv, github]\n  severity: [high, critical]\n  autoBlock: true\n  updateInterval: 12\n```\n\n### 6. Block Recently Published Packages\n\n```yaml\n# Protect against newly published malicious packages\npackageAge:\n  enabled: true\n  minPackageAgeDays: 7       # Package must exist for 7 days\n  minVersionAgeDays: 3       # Version must exist for 3 days\n  warnOnly: false            # Block, don't just warn\n```\n\n### 7. Block Packages by Author/Region\n\n```yaml\n# Block packages from specific authors, emails, or regions\nauthorFilter:\n  enabled: true\n  # Block specific author names\n  blockedAuthors:\n    - \"Suspicious Author\"\n    - \"Known Bad Actor\"\n  # Block author names matching patterns\n  blockedAuthorPatterns:\n    - \"^Bot.*\"\n    - \".*Spammer$\"\n  # Block specific email addresses\n  blockedEmails:\n    - \"malicious@example.com\"\n  # Block email patterns\n  blockedEmailPatterns:\n    - \".*@temporary-mail\\\\.com$\"\n  # Block entire email domains\n  blockedEmailDomains:\n    - \".ru\"           # All .ru domains\n    - \"yandex.ru\"     # Specific domain\n    - \"mail.ru\"\n  # Block by region (includes multiple common domains)\n  blockedRegions:\n    - \"ru\"            # Russia (.ru, yandex.ru, mail.ru, etc.)\n    - \"cn\"            # China (.cn, qq.com, 163.com, etc.)\n    - \"by\"            # Belarus\n    - \"kp\"            # North Korea\n  # Require author information\n  requireVerifiedEmail: true\n  # Warn-only mode (don't block, just log)\n  warnOnly: false\n```\n\n## 🔐 Security Best Practices\n\n1. **Enable CVE Scanning** - Automatically detect and block vulnerable packages\n2. **Use Whitelist Mode** - For maximum security in sensitive environments\n3. **Enforce License Compliance** - Prevent legal issues with license filtering\n4. **Enable Package Age Filtering** - Block newly published packages to prevent supply chain attacks\n5. **Enable Author Filtering** - Block packages from untrusted authors or regions\n6. **Enable Metrics** - Track security events for audit and compliance\n7. **Regular Updates** - Keep the plugin and CVE database cache updated\n8. **Test Rules** - Use dry run mode (planned) before applying strict rules\n9. **Monitor Logs** - Review security logs regularly for suspicious activity\n\n## 🐛 Troubleshooting\n\n### Plugin not loading\n- Verify Verdaccio version \u003e= 5.0.0\n- Check plugin is listed in `config.yaml` under `filters`\n- Ensure plugin is installed globally or linked correctly\n\n### CVE scanning not working\n- Check internet connectivity to OSV API (https://api.osv.dev)\n- Verify `cveCheck.enabled` is `true`\n- Check cache directory permissions\n- Review logs for API errors\n\n### Tests failing\n- Ensure Node.js \u003e= 22.0.0\n- Run `npm install` to update dependencies\n- Clear Jest cache: `npx jest --clearCache`\n\n### Package blocked unexpectedly\n- Check logs for the reason: `logger.level: debug`\n- Review all active rules (patterns, scopes, CVE, license)\n- In whitelist mode, ensure package is explicitly approved\n\n## 📄 License\n\nMIT © [Vitaliy Ponomarenko](https://github.com/ponomarenko)\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Run tests (`npm test`)\n4. Commit your changes (`git commit -m 'Add amazing feature'`)\n5. Push to the branch (`git push origin feature/amazing-feature`)\n6. Open a Pull Request\n\n## 📞 Support\n\n- **Issues**: [GitHub Issues](https://github.com/ponomarenko/verdaccio-security-filter/issues)\n- **Documentation**: [README](./README.md)\n- **Examples**: [Configuration Examples](./examples)\n\n## 🙏 Acknowledgments\n\n- [Verdaccio](https://verdaccio.org/) - The awesome private npm registry\n- [OSV](https://osv.dev/) - Open Source Vulnerabilities database\n- All contributors and users of this plugin\n\n---\n\n**Made with ❤️ for the npm security community**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fponomarenko%2Fverdaccio-security-filter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fponomarenko%2Fverdaccio-security-filter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fponomarenko%2Fverdaccio-security-filter/lists"}