Skip to content

fix(deps): patch remaining npm security vulnerabilities via react-router v7 and overrides - #382

Merged
michaelrobertsutton merged 1 commit into
mainfrom
fix/npm-security-overrides-round2
Jul 30, 2026
Merged

fix(deps): patch remaining npm security vulnerabilities via react-router v7 and overrides#382
michaelrobertsutton merged 1 commit into
mainfrom
fix/npm-security-overrides-round2

Conversation

@michaelrobertsutton

Copy link
Copy Markdown
Collaborator

Summary

  • Bumps react-router-dom 6.30.4 → 7.18.2 and adds/updates npm overrides for brace-expansion, svgo, shell-quote, fast-uri, http-proxy-middleware, body-parser, @babel/core, and postcss.
  • Closes 13 of the 16 currently-open Dependabot alerts in code. The remaining 3 (webpack-dev-server, alerts 35/44/45) have no compatible patch under react-scripts 5.0.1 and will be dismissed as not_used separately (build-time-only, prod serves a static build via serve).
  • Adds frontend/src/setupTests.js (TextEncoder/TextDecoder polyfill) and a jest.moduleNameMapper entry for react-router's ./dom subpath export — both required for CRA 5's frozen Jest 27 to resolve react-router v7's package structure. Confirmed by reproducing the failure and fixing it, not assumed.

Alert → fix mapping

Alert Package Installed before Installed after Status
54 brace-expansion 1.1.14 1.1.18 ✅ fixed
53 body-parser 1.20.5 1.20.6 ✅ fixed
52, 51 react-router 6.30.4 7.18.2 ✅ fixed
50 react-router-dom 6.30.4 7.18.2 ✅ fixed
49 svgo 1.3.2 / 2.8.2 2.8.3 ✅ fixed (verified with a real SVG-import build probe — see below)
48 shell-quote 1.8.4 1.10.0 ✅ fixed
47, 46 fast-uri 3.1.2 3.1.4 ✅ fixed
41 http-proxy-middleware 2.0.9 2.0.10 ✅ fixed
40 @babel/core 7.29.0 7.29.7 ✅ fixed
35, 44, 45 webpack-dev-server 4.15.2 unchanged dismissal (no compatible patch; see Phase 6 note below)

Each row above was checked against the actual installed version in package-lock.json, not inferred from npm audit's summary.

A note on npm audit's 53-vulnerability count

npm audit reports 53 high-severity findings on this branch. This is a verified reporting artifact, not a regression:

  • Two brand-new brace-expansion advisories were published this week (GHSA-3jxr-9vmj-r5cp on 2026-07-20, GHSA-mh99-v99m-4gvg on 2026-07-24) extending coverage up to <=5.0.7. Neither is among the 16 target alerts.
  • Once brace-expansion is pinned via an override, npm audit can no longer propose a simple version bump as the fix, so it falls back to listing every ancestor in the eslint/jest/workbox dependency chains (all build-time-only, never shipped) instead of one line item.
  • The correct fix for alert 54 uses a version-qualified override key ("brace-expansion@1": "^1.1.16") so only the 1.x instance (used by minimatch@3.1.5, itself only used by eslint/jest/workbox at build time) is touched — the filelist package's minimatch@5.1.9 still gets its own compatible brace-expansion@2.x. Verified via npm ls brace-expansion.
  • Escaping the newer, broader advisory (<=5.0.7) would require forcing brace-expansion@5.x onto minimatch@3.1.5, a package frozen inside react-scripts since 2022 — real compatibility risk, not required by any of the 16 target alerts, and out of scope here.

New advisory found during this work (not yet a Dependabot alert on this repo)

npm audit also flags react-router-dom@7.18.2 against GHSA-qwww-vcr4-c8h2 ("RSC Mode CSRF Bypass"), published 2026-07-24 — 6 days before this branch. Read the advisory text directly: it only affects apps using the unstable RSC APIs. Lenny uses none (BrowserRouter/Routes/Route/Link/NavLink/Navigate, no RSC). Staying at 7.18.2 is correct; escaping this advisory would require react-router v8 (a major bump — alerts 51/52 require ≥7.18.0, so every 7.x that closes them sits inside this advisory's range; 8.0+ is the only version outside it). GitHub's own Dependabot scan hasn't picked this up yet — it plausibly will shortly after this merges. Flagging now so a future alert here isn't a surprise.

Verification

  • Lint: ruff check + ruff format --check — clean (unchanged from main, no backend code touched).
  • Unit: 503 passed, 0 failed.
  • CI-equivalent integration suite (real HAPI containers): 29 passed, 7 skipped, 0 failed.
  • npm run build: compiles successfully, including the SVG-import svgo probe (temporarily wired a real SVG import through @svgr/plugin-svgo — the one path the flat svgo override could have silently broken — confirmed clean, then removed the scratch files).
  • npm test -- --watchAll=false: all 6 suites, 88/88 tests pass (required the two jest fixes above; failed without them — this is the one thing CI itself never runs, so it needed this level of scrutiny).
  • npm start: dev server compiles and serves (confirms webpack-dev-server 4.x + shell-quote/http-proxy-middleware/body-parser overrides didn't break the dev server).
  • Full local docker stack, walked with a real browser:
    • / → redirects to /measures; /measures, /jobs, /results, /validation, /settings all load with zero console errors.
    • Clicked the Calculate link on a measure row — confirmed the Link to={/jobs?newCalc=...} query-param navigation from MeasuresPage.js works correctly with react-router v7.
    • Ran a full measure calculation through the UI (CMS122, 56 patients) end to end, then navigated into /results/1 (useParams route) and confirmed patient-level results render correctly.
    • Uploaded a validation bundle and ran a full validation through the UI (CMS124, 33 patients, 100% pass rate) with zero console errors.
  • npm audit: 13/16 target alerts confirmed closed by direct version check (see table above); the artifact-count caveat is documented above rather than glossed over.

Pre-existing bug found during this work (out of scope, filed separately)

While walking every route, /groups returned a raw server 404 on direct navigation. Root cause: frontend/public/serve.json's rewrites list has an entry for every other client route (/measures, /jobs, /results, /results/:jobId, /validation, /settings) but is missing /groups — unrelated to this PR, predates it, and would behave identically on react-router v6. No nav link currently exposes /groups, so blast radius is low. Filed as a separate issue rather than fixed here to keep this PR scoped to the security patch.

Related issue

N/A — see the separate issue filed for the /groups finding above.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • Infrastructure / CI/CD
  • Chore (deps, tooling, lockfile)

Checklist

  • Tests added or updated (setupTests.js polyfill + jest config, required for react-router v7 under CRA's Jest)
  • docs/ updated (if architecture or API changed) — N/A, no architecture change
  • No new ADRs needed, OR I've added an entry to docs/decisions.md
  • Security implications considered — this PR's entire purpose is closing security alerts; see mapping table and audit-artifact/new-advisory notes above

Test plan

  • cd frontend && npm ci && npm run build && npm test -- --watchAll=false
  • cd backend && ruff check app/ tests/ && python3 -m pytest tests/ --ignore=tests/integration
  • ./scripts/run-integration-tests.sh --ignore=tests/integration/test_golden_measures.py --ignore=tests/integration/test_connectathon_measures.py --ignore=tests/integration/test_full_workflow.py --ignore=tests/integration/test_groups_dropdown.py --ignore=tests/integration/test_full_jobs_pipeline.py --ignore=tests/integration/test_factory_reset.py
  • docker compose up -d --build, then walk /measures → click Calculate → run a measure calc → view /results/:jobId, and /validation → upload a bundle → run a validation.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

…ter v7 and overrides

Bumps react-router-dom 6.30.4 -> 7.18.2 and adds/updates overrides for
brace-expansion, svgo, shell-quote, fast-uri, http-proxy-middleware,
body-parser, @babel/core, and postcss, closing 13 of the 16 open
Dependabot alerts (the remaining 3, webpack-dev-server, have no
compatible patch under react-scripts 5.0.1 and are handled via
dismissal, not a code change).

Adds src/setupTests.js (TextEncoder/TextDecoder polyfill) and a jest
moduleNameMapper for react-router's ./dom export, both required for
CRA 5's frozen Jest 27 to resolve react-router v7's package exports.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133KzW3jzNgtEkcbKZmytyC
@michaelrobertsutton
michaelrobertsutton merged commit 858ff14 into main Jul 30, 2026
6 checks passed
@michaelrobertsutton
michaelrobertsutton deleted the fix/npm-security-overrides-round2 branch July 30, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant