From 7a6ad350bd7d1ff07b22ae86ebf623f6a5cf6b76 Mon Sep 17 00:00:00 2001 From: Courier Date: Sat, 3 Oct 2026 05:44:20 +0000 Subject: [PATCH] fix(ci): pass --include=optional in audit script so --omit=dev survives .npmrc include=dev (#1162) npm gives include=dev precedence over --omit=dev even on the command line, so npm run audit evaluated the dev tree and failed on the dev-only, unfixable braces * advisory GHSA-vfj7-8cjw-p6xm via eslint-config-next. The CLI --include=optional replaces the project-level include list, restoring a prod+optional-only audit. --- .npmrc | 1 + SECURITY-ACCEPTED-RISKS.md | 7 ++++--- package.json | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.npmrc b/.npmrc index 7a4a3138..092987f9 100644 --- a/.npmrc +++ b/.npmrc @@ -1,4 +1,5 @@ # Ensure reproducible local validation: always install devDependencies. # Overrides global `omit=dev` so `npm ci` installs everything needed # for `npm run typecheck` and `npm run test` to work from a clean checkout. +# CAUTION: include=dev overrides --omit=dev (npm precedence), which is why scripts.audit passes --include=optional. See SECURITY-ACCEPTED-RISKS.md and issue #1162. include=dev diff --git a/SECURITY-ACCEPTED-RISKS.md b/SECURITY-ACCEPTED-RISKS.md index d198710c..cd7184a1 100644 --- a/SECURITY-ACCEPTED-RISKS.md +++ b/SECURITY-ACCEPTED-RISKS.md @@ -1,10 +1,10 @@ # Accepted Security Risks -**Last updated: 2026-08-15** +**Last updated: 2026-10-03** There are currently no accepted npm runtime advisories. -`npm audit --omit=dev` reports **0 vulnerabilities** across 17 production dependencies. +`npm run audit` (`npm audit --omit=dev --include=optional`, plus fetch-retry flags; see Previous Resolution History for why `--include=optional` is required) reports **0 vulnerabilities** across 17 production dependencies. ## Non-NPM Risks @@ -29,7 +29,7 @@ The following risks are tracked beyond npm advisories: - The project uses 17 production dependencies with transitive chains managed by npm. - Key deep-chain dependencies: `next` (framework), `@modelcontextprotocol/sdk` (MCP protocol), `prisma` / `@prisma/client` (ORM). -- **Mitigation:** Renovate keeps dependencies updated; `npm audit --omit=dev --audit-level=high` runs on every push to `main` and every pull request via `.github/workflows/security-audit.yaml` (separate from the main CI workflow) and fails the build on high/critical vulnerabilities. +- **Mitigation:** Renovate keeps dependencies updated; `npm run audit` (`npm audit --omit=dev --include=optional --audit-level=high`) runs on every push to `main` and every pull request via `.github/workflows/security-audit.yaml` (separate from the main CI workflow) and fails the build on high/critical vulnerabilities. ### Groomer Autonomous Issue Rewrites (accepted risk) @@ -60,3 +60,4 @@ The following previously accepted risks have been retired: |---|---|---| | Trivy action pinned to SHA | ✅ Resolved | `aquasecurity/trivy-action@ed142fd` (v0.36.0). The SHA pin is intentional: trivy is the release gate, so a floating tag must not reach a release build. Renovate's `github-tags` datasource cannot resolve a bare SHA pin (it only produced a `no-result` lookup failure on the dashboard), so the action is excluded from Renovate in `renovate.json` (`matchPackageNames: ["aquasecurity/trivy-action"]`, `enabled: false`) and is bumped manually, with the version comment, after reviewing an upstream release. | | `.npmrc` invalid omit config | ✅ Resolved | Fixed `omit=` → `omit=dev` | +| `.npmrc` `include=dev` neutralized `npm audit --omit=dev` (CI Security Audit red, #1162) | ✅ Resolved | `scripts.audit` now passes `--include=optional`, replacing the project-level include list on the CLI so the audit covers prod + optional deps only. The `braces *` advisory (GHSA-vfj7-8cjw-p6xm) is dev-only (`eslint-config-next` chain), has no patched version, and is intentionally out of scope for the production audit. Do NOT revert `.npmrc` to `omit=`: npm 11 flags the empty value with an invalid-config warning on every command. | diff --git a/package.json b/package.json index 248b0ef4..e309878d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dev": "next dev", "build": "NODE_ENV=production next build", "start": "next start", - "audit": "npm audit --omit=dev --audit-level=high --fetch-retries=5 --fetch-timeout=120000 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000", + "audit": "npm audit --omit=dev --include=optional --audit-level=high --fetch-retries=5 --fetch-timeout=120000 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000", "lint": "NODE_ENV=development eslint .", "test": "NODE_ENV=development vitest run", "test:watch": "NODE_ENV=development vitest", @@ -63,7 +63,8 @@ "vitest": "^5.0.0" }, "//": { - "overrides": "These pins exist to remediate npm advisories (originally added in #350). DO NOT remove without verifying the originating transitive deps have shipped patched versions: postcss ^8.5.10 (XSS-class advisory), sharp ^0.35.0 (libvips CVE-2026-33327/33328/35590/35591, #675 — already satisfied transitively by next@16.3.0's optional dep `sharp: ^0.35.3`, but the override survives any future `next` downgrade), deepmerge-ts ^8.0.0 (GHSA-ggr8-5vv4-36mx stack-exhaustion — pulled in by @prisma/config <=6.13.0-dev.1 and the transitive prisma <=7.10.0-integration-fix-prisma-publish-token.1, #761), mysql2 ^3.22.0 (GHSA-3f6p-5ww8-9rcr plaintext-credential leak via mysql_clear_password auth-plugin downgrade — pulled in by the transitive prisma >=6.20.0-dev.1 / <=7.10.0, #897). npm validates every entry of `overrides` strictly, so this rationale lives at the top level rather than inside the `overrides` block." + "overrides": "These pins exist to remediate npm advisories (originally added in #350). DO NOT remove without verifying the originating transitive deps have shipped patched versions: postcss ^8.5.10 (XSS-class advisory), sharp ^0.35.0 (libvips CVE-2026-33327/33328/35590/35591, #675 — already satisfied transitively by next@16.3.0's optional dep `sharp: ^0.35.3`, but the override survives any future `next` downgrade), deepmerge-ts ^8.0.0 (GHSA-ggr8-5vv4-36mx stack-exhaustion — pulled in by @prisma/config <=6.13.0-dev.1 and the transitive prisma <=7.10.0-integration-fix-prisma-publish-token.1, #761), mysql2 ^3.22.0 (GHSA-3f6p-5ww8-9rcr plaintext-credential leak via mysql_clear_password auth-plugin downgrade — pulled in by the transitive prisma >=6.20.0-dev.1 / <=7.10.0, #897). npm validates every entry of `overrides` strictly, so this rationale lives at the top level rather than inside the `overrides` block.", + "audit": "The --include=optional flag exists because .npmrc sets include=dev (so npm ci installs devDependencies even when a developer's global npm config omits them), and npm gives include=dev precedence over --omit=dev even on the command line. Without this flag, npm run audit evaluated the dev tree and failed on the dev-only, unfixable braces * advisory GHSA-vfj7-8cjw-p6xm (eslint-config-next -> @next/eslint-plugin-next -> fast-glob -> micromatch -> braces, issue #1162). Passing --include=optional on the CLI replaces the project-level include list, restoring a prod+optional-only audit with no invalid-config warnings." }, "overrides": { "postcss": "^8.5.10",