Skip to content

fix(security): close 10 alerts via overrides, re-triage the full alert set - #104

Merged
mmcky merged 5 commits into
mainfrom
copilot/fix-react-router-vulnerability
Aug 6, 2026
Merged

fix(security): close 10 alerts via overrides, re-triage the full alert set#104
mmcky merged 5 commits into
mainfrom
copilot/fix-react-router-vulnerability

Conversation

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Original scope (Copilot)

Dependabot alert for @remix-run/node (GHSA-9583-h5hc-x8cw / CVE-2025-61686): path traversal via createFileSessionStorage() with an unsigned cookie, patched only in 2.17.2 (Remix v2 / React Router v7).

Reachability: not reachable. createFileSessionStorage is never called in this codebase — the only session is getThemeSession in app/root.tsx, which is cookie-backed via @myst-theme/site. Verified independently during review. The version isn't bumped because the only fix is Remix v2, deliberately deferred (Remix ≥1.19 causes an infinite reload loop under the mystmd CLI's SSR — #63).

The original change was to add the CVE-2025-61686 alias and advance the snapshot date. The alias is kept. The date bump is what prompted the expansion below.

Why this PR grew

Advancing "Snapshot as of" asserts a re-triage that hadn't happened. Measured by package, SECURITY.md covered 13 of the 18 packages with open alerts — and four of the five uncovered ones had backward-compatible patched releases, which is precisely the case this file's own policy says to fix with an overrides entry rather than defer:

Where a vulnerable transitive dependency has a backward-compatible patched release, we pull it forward with an overrides entry… rather than bumping a major version of the toolchain.

So the gap wasn't only documentation — it was actionable work sitting undone behind a date stamp.

Overrides added — 10 alerts closed

Package Was Now Alerts closed
brace-expansion 1.1.15, 5.0.6 1.1.18, 5.0.9 3 high (ReDoS via exponential expansion)
js-yaml 3.14.2, 4.1.1 3.15.1, 4.3.1 2 high + 2 medium (quadratic CPU via merge-key chains)
sanitize-html 2.12.1, 2.17.1 2.17.6 1 medium (incomplete URI-scheme validation)
@babel/core 7.29.0 7.29.7 1 low (file read via sourceMappingURL)

brace-expansion and js-yaml each have two majors resolved in the tree, so those overrides are version-scoped, following the existing ws@^8.0.0 precedent. sanitize-html is pinned exactly to 2.17.5 (the advisory-fixed floor): 2.17.6 raises engines.node to >=22.12.0 — conflicting with the theme's node >=20 support — and swaps htmlparser2 to the ESM-only v12; CI runs node 24 and would never have surfaced that. The brace-expansion 5.x floor is ^5.0.9, matching the advisory DB's 5.x patched versions (5.0.8/5.0.9) rather than this repo's alert view, which only surfaces the 1.x ranges for two of the three advisories.

The fifth uncovered package, linkify-it, is a genuine major (4→5) with no 4.x fix — but it reaches the tree only as a markdown-it dependency, and markdown-it is already deferred as 13→14 (which requires linkify-it ^5). It's now named explicitly under that deferral rather than left to be inferred.

Documentation corrections found along the way

  • The "Report a vulnerability" link — the one URL in the file that most needs to be right — still pointed at the pre-rename quantecon-theme-src, as did the #63 link. Both updated (same staleness Use the current repo name in PLAN.md's comparison table #110 fixed in PLAN.md).
  • The shell-quote row still read ^1.8.4 after build(deps-dev): bump shell-quote from 1.8.4 to 1.10.0 #108 moved the override to ^1.10.0.
  • Added a note that the triage buckets are matched by package, so a package appearing nowhere in the section is untriaged rather than implicitly deferred — the ambiguity that let this drift accumulate.

Adversarial review

The expanded change was itself reviewed by an independent multi-agent pass (overrides/lockfile semantics, every SECURITY.md claim re-derived from the Dependabot API, upstream-changelog behavioral risk), which caught both floor defects above plus three doc staleness items now fixed: the ws (7→8) deferral (ws@7 has no open alerts since #103), two missing GHSAs in the tar enumeration, and the react-router row not recording that two advisories have no 6.x fix (first patched in 7.18.0). The review also confirmed: the version-range override keys behave as intended (per-major scoping, verified in the resolved lockfile), the full lockfile diff has an empty "unexplained" bucket, no vulnerable versions remain anywhere in the tree, and the @jupyterlab/apputils range-override is legal, intended npm behavior (now noted in SECURITY.md).

Verification

  • All 18 packages with open alerts are now named in SECURITY.md, and every override row matches package.json exactly (both checked programmatically).
  • Overrides resolve to the patched versions in the installed tree.
  • Typecheck, 13 unit tests, and 13 visual tests pass. The visual suite is the meaningful check here — sanitize-html sits in MyST's render path.

Snapshot date set to the day the re-triage actually happened.

Copilot AI changed the title [WIP] Fix React Router path traversal vulnerability in session storage docs(security): triage GHSA-9583-h5hc-x8cw / CVE-2025-61686, update snapshot date Jul 24, 2026
Copilot finished work on behalf of mmcky July 24, 2026 04:27
Copilot AI requested a review from mmcky July 24, 2026 04:27
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://QuantEcon.github.io/quantecon-theme.mystmd/pr-preview/pr-104/

Built to branch gh-pages at 2026-08-06 06:50 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🎭 Visual regression results

passed  13 passed
skipped  1 skipped

Details

stats  14 tests across 1 suite
duration  27.8 seconds
commit  faadaa7

Skipped tests

mobile-chrome › theme.spec.ts › QuantEcon theme — visual regression › launch-colab

mmcky added 2 commits August 6, 2026 15:26
…t set

Builds on Copilot's CVE-alias addition. Reviewing that PR surfaced that the
snapshot date was being advanced without a re-triage: measured by package,
SECURITY.md covered 13 of the 18 packages with open alerts, and four of the
five uncovered ones had backward-compatible patched releases — exactly the
case this file's own policy says to fix with an `overrides` entry rather
than defer.

Overrides added (10 alerts closed):

  brace-expansion  1.1.15 -> 1.1.18, 5.0.6 -> 5.0.9   3 high (ReDoS)
  js-yaml          3.14.2 -> 3.15.1, 4.1.1 -> 4.3.1   2 high + 2 medium
  sanitize-html    2.12.1/2.17.1 -> 2.17.6            1 medium
  @babel/core      7.29.0 -> 7.29.7                   1 low

brace-expansion and js-yaml each have two majors in the tree, so those are
version-scoped like the existing `ws@^8.0.0` entry.

The fifth, `linkify-it`, is a genuine major (4->5) with no 4.x fix, but it
reaches the tree only via markdown-it@13 — already deferred as 13->14, and
markdown-it@14 requires linkify-it ^5. Named explicitly under that deferral
rather than left to be inferred.

Also: SECURITY.md's own "Report a vulnerability" link still pointed at the
pre-rename quantecon-theme-src (as did the #63 link), and the shell-quote
row still read ^1.8.4 after #108 moved it to ^1.10.0. Both corrected, and
the snapshot date set to the day the re-triage actually happened.

Verified: all 18 packages with open alerts are now named in the file;
overrides resolve to the patched versions; typecheck, 13 unit tests and 13
visual tests pass (sanitize-html sits in MyST's render path, so the visual
suite is the meaningful check).
@mmcky mmcky changed the title docs(security): triage GHSA-9583-h5hc-x8cw / CVE-2025-61686, update snapshot date fix(security): close 10 alerts via overrides, re-triage the full alert set Aug 6, 2026
An independent review of the override set found two real defects:

- sanitize-html: the ^2.17.5 caret resolved 2.17.6, which raises
  engines.node to >=22.12.0 — contradicting this theme's declared node
  >=20 support — and swaps htmlparser2 from v8 to the ESM-only v12. CI
  never noticed because it runs node 24. Now pinned EXACTLY to 2.17.5:
  the advisory-fixed floor (GHSA-vccv-cmxp-4j9h patched at 2.17.5), no
  engines constraint, htmlparser2 v10. The tree keeps a single
  sanitize-html copy.
- brace-expansion@^5.0.0: the ^5.0.7 floor was below the 5.x patched
  versions in the GitHub advisory DB (GHSA-mh99 patched 5.0.8, GHSA-rgw5
  patched 5.0.9) — this repo's Dependabot alerts only surface the 1.x
  ranges for those two, which is what the floor was mistakenly read
  from. The installed 5.0.9 was already safe; the declared floor now
  matches it (^5.0.9).

SECURITY.md corrections from the same review:

- Both rows updated with the reasoning above; the sanitize-html row also
  notes the override knowingly forces @jupyterlab/apputils past its
  declared ~2.12.1 range.
- The "ws (7->8)" deferral was stale — ws@7 has no open alerts since
  7.5.12 (#103) covers the last patched 7.5.11. Removed from the
  deferred list; the ws@^8.0.0 override row records it.
- The tar deferral enumeration was missing two of the eight open GHSAs
  (GHSA-vmf3-w455-68vh, GHSA-w8wr-v893-vjvp) — added.
- The react-router row now records that GHSA-337j-9hxr-rhxg and
  GHSA-wrjc-x8rr-h8h6 have no 6.x fix at all (first patched in 7.18.0).

Verified: all open-alert packages named in SECURITY.md and every
override row matches package.json (both checked programmatically);
resolved tree is sanitize-html 2.17.5 / htmlparser2 10.1.0 /
brace-expansion 1.1.18 + 5.0.9; typecheck, 13 unit and 13 visual
tests pass.
@mmcky
mmcky marked this pull request as ready for review August 6, 2026 07:00
Copilot AI lite review requested due to automatic review settings August 6, 2026 07:00
@mmcky
mmcky merged commit 8653f98 into main Aug 6, 2026
4 checks passed
@mmcky
mmcky deleted the copilot/fix-react-router-vulnerability branch August 6, 2026 07:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the repo’s dependency-security posture by expanding overrides to pull vulnerable transitive packages up to patched versions, and updates SECURITY.md to reflect a full re-triage snapshot and corrected links.

Changes:

  • Add several npm overrides (version-scoped where multiple majors coexist) to resolve transitive vulnerable dependencies without major toolchain upgrades.
  • Update SECURITY.md with corrected repository links, expanded override documentation, and an updated snapshot date + clearer triage rules.
  • Regenerate package-lock.json to reflect the new resolved dependency graph (e.g., updated js-yaml, brace-expansion, sanitize-html, @babel/*).

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
SECURITY.md Updates vulnerability reporting links and documents the expanded override/triage set with a new snapshot date.
package.json Adds new overrides entries intended to force patched transitive dependency versions.
package-lock.json Lockfile updates reflecting the overridden resolutions and resulting dependency tree changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread package.json
Comment on lines +75 to +78
"js-yaml@^3.0.0": "^3.15.0",
"js-yaml@^4.0.0": "^4.3.0",
"sanitize-html": "2.17.5",
"@babel/core": "^7.29.6"
Comment thread SECURITY.md
Comment on lines +37 to +40
| `js-yaml@^3.0.0` | `^3.15.0` | GHSA-52cp-r559-cp3m / GHSA-h67p-54hq-rp68 — quadratic CPU consumption via YAML merge-key chains |
| `js-yaml@^4.0.0` | `^4.3.0` | same advisories, 4.x copy |
| `sanitize-html` | `2.17.5` (exact) | GHSA-vccv-cmxp-4j9h — incomplete URI-scheme validation. Pinned exactly: 2.17.5 is the advisory-fixed floor, while 2.17.6 raises `engines.node` to `>=22.12.0` (conflicting with this theme's node `>=20` support) and swaps htmlparser2 to the ESM-only v12. Note this override knowingly forces `@jupyterlab/apputils` past its declared `~2.12.1` range (CI, including the real-lecture preview build, is green on the forced version) |
| `@babel/core` | `^7.29.6` | GHSA-4x5r-pxfx-6jf8 — arbitrary file read via `sourceMappingURL` comment (low; build-time) |
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.

3 participants