From ae9df10b56b2fca73fa514cc8a6f34dbcb828f4f Mon Sep 17 00:00:00 2001 From: stxkxs <139715017+stxkxs@users.noreply.github.com> Date: Sat, 8 Aug 2026 00:18:19 -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 | 17 +++++++++++++---- package-lock.json | 6 +++--- package.json | 1 + 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 76ae96b..14f61d4 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -42,7 +42,7 @@ jobs: # the build gate (exit-code 1) makes Trivy mark the SARIF invocation # unsuccessful whenever a finding exists, which GitHub surfaces as # "Trivy is reporting errors" / a code-scanning configuration error. - - 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 @@ -68,7 +68,7 @@ jobs: # step already downloaded (skip-db-update). Separate from the SARIF upload # so a finding fails CI without poisoning the code-scanning analysis. - name: gate on HIGH/CRITICAL - uses: aquasecurity/trivy-action@master + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: scan-type: config scan-ref: Dockerfile @@ -80,10 +80,19 @@ 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 # Report step: always upload a clean SARIF (exit-code 0) — see trivy-config. - - uses: aquasecurity/trivy-action@master + - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: scan-type: fs scan-ref: . @@ -105,7 +114,7 @@ jobs: category: trivy-fs # Gate step: fail the build on HIGH/CRITICAL, reusing the cached DB. - name: gate on HIGH/CRITICAL - 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 f037451..f886970 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5694,9 +5694,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 5e6817f..41e91a8 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "fast-uri": "^3.1.4", "form-data": "^4.0.6", "gaxios": "^7.3.0", + "nanoid": "^3.3.17", "postcss": "^8.5.15", "protobufjs": "^7.6.4", "qs": "^6.15.2",