fix(security): @nuxtjs/mdc ^0.22.2 (CVE-2026-63671) — hold for 3.0 #59
No reviewers
Labels
No labels
idea
points
1
points
13
points
2
points
3
points
5
points
8
priority
p0
priority
p1
priority
p2
priority
p3
state
blocked
state
done
state
in-progress
state
ready
state
review
state
triage
status
declined
status
in-progress
status
planned
status
proposed
status
shipped
status
under-review
type
bug
type
epic
type
feature
type
spike
type
story
type
task
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Blocks
You do not have permission to read 1 dependency
Reference
tti/tti-ux!59
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/mdc-cve-2026-63671"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Moves the layer's
@nuxtjs/mdcrange from^0.21.1to^0.22.2, clearing CVE-2026-63671 / GHSA-mxm6-v9r6-r94c (HIGH). Below 0.22.1, mdc's parse-time sanitizer letsjavascript:on an SVG<a xlink:href>and adata:text/htmlsrcthrough, andparseMarkdownenables raw HTML by default. Everything tux renders through MDC (TuxProse,TuxMarkdownEditor,/design/*,/changelog,/install) sits behind that sanitizer, and so does every consumer that extends the layer.Supersedes Renovate's #58, which floors at
^0.22.0(0.22.0 is still vulnerable) and stays red on both trivy gates: its lockfile nests a vulnerable0.21.1under the@tti/tti-ux@2.0.0that npm installs forpackages/react's peer dependency.Changes (3 files)
package.jsondependencies["@nuxtjs/mdc"]:^0.21.1→^0.22.2. 0.22.2 is the fix plus a follow-up that also validates bound (:href) and@eventattribute names.overrides["@nuxtjs/mdc"]: "$@nuxtjs/mdc", with a"//"note. It only shapes this repo's own install (npm ignores a dependency's overrides): it moves the peer-installed@tti/tti-ux@2.0.0's copy onto the root range, leaving one mdc in the tree.package-lock.json, regenerated with npm 12.0.2. npm 11.12.1 does not propagate the override through the workspace peer and keeps the nested 0.21.1 (tried the$reference, a literal range and two scoped forms). The npm 12 lockfile is exactly the npm 11 one minus that nested entry. Againstmainit changes only the mdc entry, plus two stale2.0.0→2.2.0version fields npm re-synced (root andpackages/react).CHANGELOG.md: an## [Unreleased]→### Securityentry.Verification
npm ci --dry-runmainis mdc 0.21.1 → 0.22.2.mdfiles with 0.21.1 and 0.22.2:href="javascript:…"; https links,/docs/…links and<img src="https://…">are untouchedNUXT_PAGES=1 nuxt generate)main's build except/changelog, which gains exactly the 21 lines of the new entry. Two builds of unchangedmaindiffer on 22 pages (inlined icon CSS, payload key order), so any other page diff is build noisenuxt typecheck,eslint .main: 11 files / 102 tests pass; the same 3 files time out onmaintoo (below)@tti/tti-ux-reacttests, run directlyPre-existing on
main— not caused by this PR@tiptap/core3.28.0,js-yaml4.3.1,sharp0.35.3,svgo4.0.2. They're the same four landscape cleared on 2026-09-15 (nis/landscape b62a1dd).@tiptap/coreis a direct editor dependency here, so it wants a real bump of the@tiptap/*set rather than an override.tux-chart-donut,tux-chart-scatterandtux-treemap.nuxt.test.tstime out insetupNuxt(the 10 s hook) onmainas well. Becausenpm testisvitest run && npm run test -w @tti/tti-ux-react, the react workspace tests are silently skipped whenever the root run fails.main's lockfile (Missing: cac/commander), asdeploy-pages.ymldocuments.npm lsflags the peer copy's mdc edge as invalid; npm 12 shows it deduped.npm lsalready exits non-zero onmainover cac/commander, and nothing in CI runs it.Why hold it for 3.0
A 2.x patch would reach almost nobody. landscape, yard, tti-ai-studio and tti-ai-studio-sampler pin
github:ttitamu/tti-ux#v1.7.0, so they can only take the layer's fix through the move to 3.0 anyway. atlas pins@tti/tti-uxat exactly2.0.0. It is the one consumer a 2.2.1 could help, since that stays inside 2.x, but it doesn't render markdown itself and the override below covers it today.The range change is something every consumer inherits. Riding the major means one dependency migration instead of two.
Until 3.0 ships, each consumer covers itself with the one-line override
"@nuxtjs/mdc": "$@nuxtjs/mdc"(plus a direct^0.22.2if it declares mdc itself). Default-branch status as of 2026-09-21:ba24548).The sampler renders LLM output through MDC. So does helm2, which uses mdc directly rather than through tux. Those two are the real exposures, and neither is fixed by this PR.
When landing with 3.0
packages/react's peer to^3.0.0in the same release. Once 3.0.0 is published and the lockfile refreshed, the peer copy carries^0.22.2itself, and the override and its"//"note can go.## [Unreleased]entry into the 3.0 section when cutting the release.maincarries three brand-logo commits (561c641..03923db) that aren't on Forgejomain; reconcile them before the release push, sincedeploy-pages.ymlbuilds from GitHubmain.AI review · advisory
Verdict: looks good — all four reviewers found nothing that needs fixing.
⚑ panel: GPT-OSS 120B · Gemma 4 31B · Devstral 2 123B · Laguna S 2.1 — 0 distinct, 0 confirmed, 0 below threshold, 0 refuted · web: not used · context: 3 files under review · no reference chunks (best-grounded: GPT-OSS 120B; smaller windows saw less)
Panel debate — how this review was reached
Grounding — context: 3 files under review · no reference chunks (best-grounded: GPT-OSS 120B; smaller windows saw less)
Round 1 — independent reviews
Synthesis — Laguna S 2.1 wrote the final review from 0 confirmed findings · promotion: support ≥ 2, and no refutation at high severity.
Transcript
rv-20260922005013-955300— full round outputs, web results, and model reasoning are viewable by anyone with access to this repository via the AI gateway.Advisory — never a merge gate. Findings are ordered by how well the panel's own evidence checks out, strongest first. React 👍/👎 on any inline comment to tell it whether it was worth flagging — that is the only feedback this system gets, and every threshold in it is tuned from those reactions. Transcript
rv-20260922005013-955300.🔧 Security-gate fix map
The gate failed on these dependency findings — fastest path to green for each:
@tiptap/corenpm update core --package-lock-onlyjs-yamlnpm update js-yaml --package-lock-onlysharpnpm update sharp --package-lock-onlysvgonpm update svgo --package-lock-onlyPosted once per head commit by the baseline gate (M2). A Renovate PR that only touches a manifest with no lockfile change is a broken pre-2026-08-06 artifact — check its diff before merging.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.