Frontend: resolve pnpm audit findings, 30 vulnerabilities - #1374
Merged
gusthoff merged 8 commits intoJul 24, 2026
Merged
Conversation
Neither package is referenced by any webpack config (webpack.common.cjs, webpack.dev.cjs, webpack.prod.cjs), any package.json script, or any .github/workflows/*.yml file — the .sass-lint.yml config they would have read is likewise orphaned. sass-lint itself has been unmaintained since 2018 and pulls in several vulnerable transitive dependencies (minimist, shelljs, merge, ajv, an old vendored minimatch), including the only critical-severity finding in `pnpm audit`. Removing the pair drops the frontend dependency tree from 984 to 864 packages and clears 12 of the 30 pnpm audit findings (1 critical, 2 high, 3 moderate) with no build or test impact: `pnpm run tsc`, `pnpm exec mocha`, and `pnpm run production` all still pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
package.json carried an eleven-entry "resolutions" block (minimist, acorn, is-svg, ssri, whatwg-url, lodash, serialize-javascript, globule/minimatch, follow-redirects, picomatch, uuid) left over from before the Yarn-to-pnpm migration. pnpm does not read a bare "resolutions" key at all — its override mechanism is a "pnpm.overrides" field in package.json or an "overrides" key in pnpm-workspace.yaml — so none of these pins have been enforced since the migration. `pnpm audit` confirms this: it still flagged several of the exact packages the pins were meant to fix (addressed separately by removing sass-lint in the previous commit). Checked each of the eleven entries against the current pnpm-lock.yaml before deciding what to keep: - is-svg, ssri, follow-redirects, and uuid no longer appear anywhere in the dependency tree; later dependency upgrades already eliminated the paths that used to pull them in. - acorn, whatwg-url, lodash, and picomatch already resolve to versions at or above the old pin on their own, with no override needed. - serialize-javascript was the one pin still doing real work: the tree carried two copies, a safe 7.0.5 pulled in by newer tooling and a vulnerable 6.0.2 pulled in by mocha (CVE-worthy RCE via RegExp.flags / Date.prototype.toISOString, plus a separate DoS advisory). This is restored as a proper pnpm-workspace.yaml override, which dedupes the tree down to the single safe copy. `pnpm exec mocha` (126 passing) is unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pnpm audit flagged the same brace-expansion DoS advisory (GHSA-3jxr-9vmj-r5cp, exponential-time expansion of consecutive non-expanding {} groups) three times, once per incompatible major version present in the tree: 1.1.15 (via clean-webpack-plugin's del dependency), 2.1.1 (via mocha's own minimatch/glob), and 5.0.6 (via @babel/cli and @typescript-eslint's minimatch). Each copy sat exactly one patch below its own safe threshold. brace-expansion's public API (a single function expanding {a,b,c}-style glob patterns into an array) has stayed stable across these majors, so a single tree-wide override to the latest safe release collapses all three copies into one instead of needing three parent-path-scoped overrides. Verified this doesn't break anything that resolves glob patterns via minimatch: `pnpm run tsc`, `pnpm exec mocha` (126 passing), `pnpm run production`, and `pnpm run eslint` (276 pre-existing problems, unchanged count) all behave identically to before the override. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pnpm audit flagged js-yaml 4.1.1 (deduped to a single copy shared by mocha, webpack-cli, and cosmiconfig) for two quadratic-complexity DoS advisories in merge-key/alias handling: GHSA-52cp-r559-cp3m (fixed at >=4.3.0) and GHSA-h67p-54hq-rp68 (fixed at >=4.1.2). Since pnpm already resolves the whole tree to one js-yaml version, a single override clears both findings without touching any direct dependency. Verified: `pnpm run tsc`, `pnpm run test` (126 passing), and `pnpm run production` all behave identically to before the override. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pnpm audit flagged immutable 5.1.6 (pulled in solely by sass's internal use of the Dart-to-JS embedded compiler protocol, via sass-loader) for two high-severity DoS advisories: a 32-bit trie overflow in List (GHSA-v56q-mh7h-f735) and a hash-collision complexity blowup in Map/Set (GHSA-xvcm-6775-5m9r), both fixed at >=5.1.8. sass's own package.json already declares "immutable": "^5.1.5", so overriding to ^5.1.8 stays inside the range sass itself considers compatible rather than forcing an incompatible version on it. Verified: `pnpm run tsc`, `pnpm run test` (126 passing), and `pnpm run production` all behave identically to before the override. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pnpm audit flagged jsdiff 7.0.0 for a DoS in parsePatch/applyPatch (GHSA-73rr-hh4g-fpgx, vulnerable >=6.0.0 <8.0.3). The tree carries two copies of diff: 4.0.4 via ts-node (below the vulnerable range, left alone) and 7.0.0 via mocha's own dependency declaration, which mocha 11.7.6 (already the latest release) still pins to ^7.0.0. Scoped the override to mocha>diff specifically, so ts-node's unrelated copy isn't forced to change. Verified: `pnpm run tsc` and `pnpm run test` (126 passing, including mocha's own diff-based assertion-failure output) are unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pnpm audit flagged undici 7.26.0 (pulled in by jsdom/jsdom-global, used to build the DOM environment for the mocha test suite) for seven advisories at various severities: a TLS certificate validation bypass and cross-origin request routing issue via SOCKS5 proxy reuse (both high), a WebSocket DoS via fragment count bypass (high), Set-Cookie header injection and cross-user cache disclosure (moderate), and a keep-alive queue-poisoning issue plus a SameSite downgrade (low). All are fixed at >=7.28.0. jsdom is already at its latest release (29.1.1) and its own package.json already declares "undici": "^7.25.0", so ^7.28.0 stays inside the range jsdom itself considers compatible. Verified: `pnpm run tsc`, `pnpm run test` (126 passing, exercising the jsdom-based DOM environment throughout), and `pnpm run production` are all unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pnpm audit flagged svgo 4.0.1 (pulled in via css-minimizer-webpack-plugin -> cssnano -> cssnano-preset-default -> postcss-svgo, part of the production CSS minification pipeline) for GHSA-2p49-hgcm-8545: the removeScripts plugin leaves some executable scripts intact instead of stripping them, fixed at >=4.0.2. postcss-svgo's own package.json already declares "svgo": "^4.0.1", so ^4.0.2 stays inside the range postcss-svgo itself considers compatible. This was the last remaining pnpm audit finding: `pnpm audit` now reports 0 vulnerabilities (down from 30 at the start of this branch). Verified: `pnpm run tsc`, `pnpm run test` (126 passing), and `pnpm run production` (identical output size, same pre-existing size-limit warnings) are all unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pnpm auditonfrontend/reported 30 findings (1 critical, 17 high, 9moderate, 3 low) across the dependency tree. This branch brings that to
0 vulnerabilities, verified after every commit, without upgrading any
direct dependency's declared version.
sass-lint/sass-lint-webpack— unmaintained since 2018, unreferencedby any webpack config,
package.jsonscript, or CI workflow. Confirmeddead code and removed outright (drops the tree from 984 to 864 packages).
package.jsoncarried an 11-entry Yarn-eraresolutionsblock leftover from the pre-pnpm migration. pnpm does not read a bare
resolutionskey — its own override mechanism isoverrides:inpnpm-workspace.yaml— so none of those pins had been enforced sincethe migration, silently exposing findings the original pins were meant
to prevent (confirmed by cross-referencing the pins against what
pnpm auditwas still flagging).brace-expansion,js-yaml,immutable,mocha'sdiff,undiciviajsdom,svgo) were each fixed with a scopedpnpm-workspace.yamloverride, chosen to stay inside the version rangethe actual consuming package already declares as compatible (e.g.
undici: ^7.28.0sits insidejsdom's own^7.25.0) — not an arbitraryversion jump. Where only one code path was vulnerable (
diffviamochavs.
ts-node's unrelated, unaffected copy), the override was scoped withparent>childsyntax instead of applying tree-wide.Test plan
pnpm audit— 0 vulnerabilities (down from 30)pnpm install --frozen-lockfile— lockfile is self-consistentpnpm run tsc— clean after every commitpnpm run cover(exact CI step fromtypescript-tests.js.yml) — 126passing, coverage unchanged
make cleanall webpack-production(exact CI step fromsphinx-content-tests.js.yml/sphinx-books-tests.js.yml) — coldrebuild, identical bundle size and warnings to before