From 07b8532e8f8b387567a8926a1696e7dd99148218 Mon Sep 17 00:00:00 2001 From: stxkxs <139715017+stxkxs@users.noreply.github.com> Date: Fri, 7 Aug 2026 20:40:07 -0700 Subject: [PATCH] fix: pnpm settings survive the pnpm 11 bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pnpm 11 does not read the `pnpm` field in package.json, and it does not fail when it finds one — it prints "The following keys were ignored: pnpm.overrides" and installs anyway. Four CVE floors live in that field here, so the pending pnpm 10 → 11 bump would have dropped all four and relocked the tree onto whatever resolves naturally, with a green install. Upstream tracks this as a security-affecting silent ignore (pnpm/pnpm#11536). osv-scanner is a required check in this repository and would have caught the CVE-driven floors coming back, but `nanoid: ^3.3.17` is not a CVE floor in the direction that matters — the caret is what keeps resolution inside the 3.x line, because `>=3.3.17` resolves to nanoid 6, which is ESM-only and is not the API postcss calls. OSV has no opinion on that, so that one would have gone through. pnpm 10 already reads pnpm-workspace.yaml, so the settings move now, ahead of the bump, rather than as part of it. No window exists where they are read from neither place. The move also lets each floor carry its own advisory and the reason for its exact form — why fast-uri is `>=4.1.2` and not the 3.x patch level, why js-yaml is scoped to the 4.x line so astro's own 5.x parser is left alone, why nanoid is a caret. That rationale was in commit bodies and nowhere in the file; JSON had no place to put it. Verified: the lockfile is byte-identical before and after the move, and the check is not vacuous — with the overrides removed the same command downgrades fast-uri 4.1.2 → 3.1.5, so an unchanged lockfile means the floors are still being applied rather than that nothing re-resolved. --- package.json | 8 -------- pnpm-workspace.yaml | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 pnpm-workspace.yaml diff --git a/package.json b/package.json index 09009e6..0f28ce4 100644 --- a/package.json +++ b/package.json @@ -30,13 +30,5 @@ "@biomejs/biome": "2.5.6", "@nanohype/error-pages": "^0.1.0", "typescript": "^6.0.3" - }, - "pnpm": { - "overrides": { - "postcss": ">=8.5.18", - "nanoid": "^3.3.17", - "fast-uri": ">=4.1.2", - "js-yaml@4": "^4.3.1" - } } } diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..be34331 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,38 @@ +# pnpm settings live here, not in package.json. +# +# pnpm 11 stopped reading the `pnpm` field in package.json entirely, and it does +# so without failing — it prints "The following keys were ignored" and installs +# anyway. An override block left behind in package.json therefore stops applying +# the moment the package manager is bumped, and the tree silently relocks onto +# the versions these floors exist to keep out. pnpm 10 already reads this file, +# so the settings live in one place across both. +# +# Every entry below is a floor over a transitive dependency, not a direct one: +# nothing here appears in package.json, and each was added because osv-scanner +# — a required check — went red on the resolved lockfile. + +overrides: + # Clears the osv-scanner gate on the resolved tree; postcss arrives via astro. + postcss: ">=8.5.18" + + # GHSA-2v37-7h3g-55p8 (CVSS 8.2) — a custom generator loops indefinitely when + # size is zero. Reached through postcss. + # + # The caret is load-bearing and must not be relaxed to `>=`: the open-ended + # form resolves to nanoid 6, which is ESM-only and is not the API postcss + # calls. The caret keeps the fix inside the 3.x line the parent supports. + nanoid: "^3.3.17" + + # GHSA-7p8r-x3mc-p8w7 (HIGH) — host confusion; a URL whose authority is + # introduced with a backslash parses to a different host than a resolver + # reaches. The advisory patches 4.x at 4.1.2 and 3.x at 3.1.5 separately; + # this tree resolves 4.x, so 4.1.2 is the correct floor here. + fast-uri: ">=4.1.2" + + # GHSA-5p4m-2wfm-xmqj / CVE-2026-59870 in js-yaml 3.x and 4.x below 4.3.1. + # + # Scoped to the 4.x line deliberately. astro 7 and Starlight pull js-yaml 5.x, + # which the advisory does not cover: an unscoped `^4.3.1` drags the site's own + # frontmatter parser down a major version, and an unbounded `>=4.3.1` collapses + # both lines to 5.x. The scoped form moves only the vulnerable resolution. + js-yaml@4: "^4.3.1"