From 9087f36d1e52f2daeb56b00ba7dbec5c1e4122f8 Mon Sep 17 00:00:00 2001 From: stxkxs <139715017+stxkxs@users.noreply.github.com> Date: Sat, 8 Aug 2026 00:18:20 -0700 Subject: [PATCH] fix: make the npm vulnerability gate see dev dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The trivy filesystem job is named for npm dependency coverage and is wired to fail the build on a fixable HIGH or CRITICAL. It reported zero while the lockfile carried one. Trivy's npm parser drops dev dependencies unless told otherwise. It says so on every run — "Suppressing dependencies for development and testing" — and the job read the resulting empty result set as a clean bill of health. Everything about the gate was right except the set of packages it was looking at. What it could not see: HIGH nanoid@3.3.16 -> 3.3.17 CVE-2026-67213 / GHSA-2v37-7h3g-55p8 A custom generator loops forever when asked for a size of zero. nanoid arrives through postcss. Sibling repositories scanning the same shape of tree with osv-scanner count dev dependencies and went red on this advisory: one package, one version, two scanners, opposite verdicts. ─── Coverage ─── TRIVY_INCLUDE_DEV_DEPS is set at job level so the report step and the gate step inherit one value and cannot drift apart. It is an environment variable because trivy-action exposes no input for the flag. A build-time package is not out of scope. It executes in CI holding this repository's credentials, which is the surface the gate exists to watch. ─── Remediation ─── An override floors nanoid at ^3.3.17. The caret is deliberate: an open-ended `>=` floor resolves to nanoid 6, which is ESM-only and is not the API postcss calls. The lockfile change touches nanoid and nothing else. ─── Action pinning ─── trivy-action moves from @master to the v0.36.0 commit. A mutable branch ref means the scanner deciding whether this repository ships is fetched from wherever that branch points on the day, which is a strange place to accept unpinned input. The same action is pinned by digest elsewhere in the org. Verified with the gate's own arguments — HIGH/CRITICAL, ignore-unfixed, dev dependencies included: one finding before the override, none after. --- .github/workflows/security.yml | 13 +++++++++++-- package-lock.json | 6 +++--- package.json | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 2995349..daffd72 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: aquasecurity/trivy-action@master + - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: scan-type: config # Scoped to the Dockerfile — the one config artifact this repo owns @@ -69,9 +69,18 @@ jobs: trivy-fs: name: trivy (filesystem vuln scan — npm deps) runs-on: ubuntu-latest + env: + # trivy's npm/pnpm parser drops dev dependencies unless told otherwise, so + # this job reported zero findings while the lockfile carried a fixable HIGH. + # A build-time dependency still executes in CI with repo credentials, which + # is the surface this gate exists to cover, and the sibling repos scanning + # the same tree with osv-scanner have always counted them — the two tools + # disagreed on the same advisory in the same org. trivy-action exposes no + # input for it; the flag is only reachable as its TRIVY_-prefixed env var. + TRIVY_INCLUDE_DEV_DEPS: "true" steps: - uses: actions/checkout@v4 - - uses: aquasecurity/trivy-action@master + - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: scan-type: fs scan-ref: . diff --git a/package-lock.json b/package-lock.json index 0f142c5..788fb2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5961,9 +5961,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index 9c9ceaa..1354205 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,8 @@ "esbuild": "^0.28.1", "axios": "^1.18.1", "body-parser": "^2.3.0", - "gaxios": "^7.3.0" + "gaxios": "^7.3.0", + "nanoid": "^3.3.17" }, "engines": { "node": ">=24"