fix(deps): scope js-yaml override so gray-matter keeps patched 3.x#1854
Conversation
The root npm override pinning js-yaml to 4.2.0 (added in #1733 for CVE-2026-53550) broke Docusaurus front-matter parsing: gray-matter@4.0.3 calls yaml.safeLoad, an API removed in js-yaml 4. This has failed the Docs Deploy job on the last two stable releases. Per the GHSA advisory for CVE-2026-53550, the 3.x line is patched in 3.15.0. Scope the override so gray-matter resolves the patched 3.x (keeping the safeLoad API) while every other consumer stays on 4.2.0 — no security regression, since 3.15.0 is the patched version for the 3.x range. Fixes #1827 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> Co-Authored-By: Claude backend-developer (Haiku 4.5) <noreply@anthropic.com>
steilerDev
left a comment
There was a problem hiding this comment.
[security-engineer] Security review of PR #1854 (dependency-manifest change — overrides.gray-matter.js-yaml scoping).
Verdict: APPROVED — no critical/high/medium findings.
Verification performed
-
CVE/GHSA validation — Pulled the advisory directly (
gh api /advisories/GHSA-h67p-54hq-rp68, CVE-2026-53550). It lists two independently patched ranges:>= 4.0.0, <= 4.1.1→ first patched4.2.0(this is what PR #1733's root override already enforces for everyone else)< 3.15.0→ first patched3.15.0
So
js-yaml@3.15.0is genuinely the correct GHSA-patched release on the 3.x line, not an approximation. I also checked the olderGHSA-mh29-5h37-fv8m(prototype pollution in merge, patched at3.14.2) —3.15.0postdates that fix too, so no regression to a previously-patched issue. -
Scoped-override correctness — Confirmed in the regenerated lockfile that the nested override resolves exactly as intended:
node_modules/gray-matter/node_modules/js-yaml→3.15.0(scoped, gray-matter subtree only)node_modules/js-yaml(root) → unchanged at4.2.0- No other package in the tree has its own nested
js-yamlcopy, so every other consumer (Docusaurus, cosmiconfig, ts-jest, etc.) still resolves to the root-overridden4.2.0. Theoverridesblock diff inpackage.jsontouches nothing except adding the one"gray-matter": { "js-yaml": "3.15.0" }line — no other override key changed.
-
npm audit clean — Extracted all 1,781 unique resolved
name@versionpairs from the PR's lockfile and queried them in bulk against the live npm advisory API (registry.npmjs.org/-/npm/v1/security/advisories/bulk) — 0 advisories returned, including for both js-yaml resolutions. This is the same data sourcenpm audititself uses, so it's an accurate stand-in for running the CLI directly. Worth flagging separately (informational, not blocking): CI'sStatic Analysisjob only runsnpm audit signatures(provenance/signing check), not a vulnerabilitynpm audit— so this manual check is currently the only vulnerability-scan gate dependency PRs get. Noting for the record; not something to fix in this PR. -
Lockfile diff scope — The
overrideschange itself is minimal and correct. The full lockfile diff is wider than just the js-yaml subtree (~49 transitive packages refreshed, mostly dev-only: Algolia/docsearch,@typescript-eslint/*,@jsonjoy.com/*/memfs, browserslist/caniuse-lite, etc., plus one production dependency:@fastify/static > lru-cache11.5.1 → 11.5.2). This matches the PR description's disclosure that a fullnpm install(per repo dependency policy — "always regenerate withnpm install, not--package-lock-only") naturally refreshes range-pinned transitive deps. None of this churn introduces a known vulnerability per the bulk-audit check in (3), and thelru-cachebump is a benign patch release. Flagging as informational only since it's disclosed, policy-compliant, and audit-clean. -
No new YAML-deserialization surface — Fetched
gray-matter@4.0.3'slib/engines.jsdirectly from the registry: its YAML engine isparse: yaml.safeLoad.bind(yaml), stringify: yaml.safeDump.bind(yaml).safeLoadis js-yaml 3.x'sSAFE_SCHEMAloader — it does not support arbitrary type instantiation via YAML tags (e.g.!!js/function), unlike the legacy unsafeload. So restoring the 3.x API surface for gray-matter doesn't reintroduce an unsafe deserialization primitive; it's the same safe entry point the plugin was written against. Also reaffirms PR #1733's original finding: js-yaml here only parses developer-authored docs front matter at build time, never untrusted input in the production server request path.
No action items. Nice, well-scoped fix — good instinct to verify the advisory's 3.x range explicitly rather than assuming any 3.x bump would do.
|
🎉 This PR is included in version 2.13.0-beta.23 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
js-yamloverride pinning4.2.0(added in fix(deps): pin js-yaml to 4.2.0 (CVE-2026-53550) #1733 for CVE-2026-53550) broke Docusaurus front-matter parsing, sincegray-matter@4.0.3callsyaml.safeLoad, an API removed in js-yaml 4 — this has failed theDocs Deployjob on the last two stable releases (runs 28778826343, 27862889701).gray-matterresolves the patched 3.x line (3.15.0, per the GHSA advisory for CVE-2026-53550) while every other consumer stays onjs-yaml@4.2.0. No security regression.npm installper repo dependency policy; unrelated transitive-dep churn (docs-workspace deps such as Algolia) reflects normal drift from range-based transitive dependencies, not intentional upgrades.Fixes #1827
Test plan
npm ls js-yamlconfirmsgray-matterresolves3.15.0(overridden) and all other consumers resolve4.2.0npm auditreports 0 vulnerabilitiesnpm run docs:buildsucceeds (previously failed withFunction yaml.safeLoad is removed in js-yaml 4)Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) noreply@anthropic.com
Co-Authored-By: Claude backend-developer (Haiku 4.5) noreply@anthropic.com