From 397600ad1ca8cd12971a6dbb6bc877d65ecd57a7 Mon Sep 17 00:00:00 2001 From: "Dr. Florian Steiner" <75360256+ProduktEntdecker@users.noreply.github.com> Date: Sun, 19 Apr 2026 16:44:40 +0200 Subject: [PATCH] chore: release v0.3.1 - Bump version to 0.3.1 - Add CHANGELOG entry for false-positive fix (#19/#20) - Add README sections: Accuracy (version resolution) and Local `npx ` limitation Closes #21 Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 25 +++++++++++++++++++++++++ README.md | 11 +++++++++++ package-lock.json | 9 +++++---- package.json | 2 +- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f10fe83..bbfe9dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.1] - 2026-04-19 + +### Fixed + +**False positives on `npx ` and other unversioned package references** + +When a package was referenced without a version (e.g. `npx vite`, +`npx playwright install chromium`), PatchPilot queried OSV without a +version field. OSV returns vulnerabilities across **all versions ever +published** in that case, surfacing patched CVEs as active threats. + +Real-world impact before the fix: +- `vite@latest` reported with 5 HIGH vulnerabilities — `vite@8.0.8` (current latest) has 0 +- `playwright@latest` reported with 1 HIGH — `playwright@1.59.1` has 0 + +Fix: when no version is specified, resolve `latest` from the npm or PyPI +registry first, then query OSV with that concrete version. On registry +failure (404, timeout, network error), falls back to the previous +unversioned query — preserves fail-closed behavior for unknown packages. + +The resolved version now appears in the hook output (`vite@8.0.8` instead +of misleading `vite@latest`). + +Closes #19, #21. + ## [0.3.0] - 2024-01-06 ### Security - Critical Fixes from Security Audit diff --git a/README.md b/README.md index 73366bb..8f2a04e 100644 --- a/README.md +++ b/README.md @@ -109,11 +109,22 @@ NODE_ENV=production npm install evil-pkg | MODERATE or LOW | **Allow** - with warning message | | None found | **Allow** | +## Accuracy + +When you reference a package without a version (e.g. `npx vite`, `npm install lodash`), +PatchPilot resolves the current `latest` from the npm or PyPI registry before querying +OSV. This avoids surfacing patched CVEs from older versions as if they affected the +release you're about to install. + +If the registry lookup fails (timeout, 404, network error), PatchPilot falls back to +querying OSV without a version — preserving fail-closed behavior for unknown packages. + ## Limitations - **Homebrew**: OSV has no vulnerability database for Homebrew packages. Brew commands are detected but not checked. - **Private registries**: Only public npm and PyPI packages are checked. - **Offline**: Requires internet connection to query OSV API. +- **Local `npx `**: PatchPilot treats `npx ` as a potential install. If the tool is already installed in `./node_modules/.bin/`, npx runs the local copy and nothing is downloaded — but the OSV check still runs against the latest published version. ## Development diff --git a/package-lock.json b/package-lock.json index de3fbd0..7797ab5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "patchpilot", - "version": "0.2.0", + "version": "0.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "patchpilot", - "version": "0.2.0", + "version": "0.3.1", "license": "MIT", "dependencies": { "shell-quote": "^1.8.3", @@ -21,6 +21,9 @@ "tsx": "^4.0.0", "typescript": "~5.8.0", "vitest": "^2.0.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -835,7 +838,6 @@ "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -1417,7 +1419,6 @@ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", diff --git a/package.json b/package.json index c54d75c..1e4bbe5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "patchpilot", - "version": "0.3.0", + "version": "0.3.1", "description": "Security scanner for vibe coders - Claude Code hook that checks packages before installation", "type": "module", "main": "dist/index.js",