Skip to content

SUPPLY-001D8 — Patch the high-severity Babel SystemJS compiler chain #453

Description

@daliu

Officer impact: None. This changes only the reviewed frontend build dependency graph; officers still use the website and current no-terminal procedures unchanged.

Officer documentation: None — no public content, navigation, collected data, permissions, deployment steps, external account, payment, incident, backup, or recovery procedure changes.

Deployment evidence: None at issue creation. Closure requires source/lock review, local and hosted exact-commit checks, and exact-main CI evidence. It must not claim website publication, Firebase deployment, provider configuration, or production behavior from those checks.

Outcome

Remove GHSA-fv7c-fp4j-7gwp / CVE-2026-44728 from the root production dependency graph with the smallest compatible lockfile-only refresh, while proving the existing React build remains equivalent and leaving unrelated dependency findings explicit.

Why this is the highest dependency-ready P0

A fresh Node 20.19.5/npm 10.8.2 npm audit --omit=dev on exact main 937e336031ffe064aa120460327538aab0d45d30 reports 4 findings: 3 high and 1 low. The GitHub-reviewed advisory rates the SystemJS transform defect high (CVSS 8.2): compiling specifically crafted input with an affected plugin can make Babel generate arbitrary-executing output.

The exact lock has:

  • @babel/preset-env@7.26.9 with @babel/plugin-transform-modules-systemjs: ^7.25.9;
  • one installed/locked SystemJS plugin at vulnerable 7.25.9;
  • no direct manifest declaration or override for either package.

The existing parent range admits patched 7.29.7; upstream identifies 7.29.4 as the first fixed 7.x release. This bounded production build-chain fix is dependency-ready. The broader firebase-tools major upgrade requires a separate Java 21 emulator/CI/release compatibility migration and must not be folded into this child.

Authoritative advisory: GHSA-fv7c-fp4j-7gwp

Invariant

The lockfile must resolve every root SystemJS transform path to a patched 7.x version, through an unchanged compatible parent range, without adding a direct dependency or override and without changing runtime application source, public behavior, deployment authority, or provider state.

Allowed transition

  • Refresh only @babel/plugin-transform-modules-systemjs and the dependency nodes npm must change to install its patched compatible release.
  • Keep package.json byte-for-byte unchanged.
  • Keep @babel/preset-env@7.26.9 and its ^7.25.9 SystemJS range unchanged.
  • Retain public npm registry URLs and valid integrity records.
  • Add a dependency-free regression test that pins the patched identity, topology, and upstream string-export behavior.
  • Update the current security/dependency evidence and tracker slice.

Failure cases

Stop and split or redesign if:

  • npm changes package.json, @babel/preset-env, an unrelated lock node, or more than the audited 16-node closure;
  • a second SystemJS plugin resolution appears or any affected <=7.29.3 resolution remains;
  • npm ls reports a new invalid/extraneous SystemJS/Babel path;
  • the optimized build changes without a reviewed, explained reason;
  • frontend, Functions, Rules, commerce-emulator, SPA, workflow, artifact, or dependency checks regress;
  • the audit still reports GHSA-fv7c-fp4j-7gwp;
  • a test, build, or emulator contacts production.

RED test

Before changing the lock, add a dependency-free Node test that fails exact main because it resolves @babel/plugin-transform-modules-systemjs@7.25.9. The test must require:

  • one installed and one locked patched 7.x resolution (>=7.29.4);
  • unchanged @babel/preset-env@7.26.9 and ^7.25.9 parent range;
  • no direct manifest dependency or override;
  • a safe upstream-derived module string-name fixture to emit computed string-property syntax rather than malformed identifier syntax;
  • the expected bounded lock topology.

Expected lock closure

The audited lock-only command is:

npm update @babel/plugin-transform-modules-systemjs --package-lock-only --ignore-scripts --legacy-peer-deps

On an isolated exact-main copy under Node 20.19.5/npm 10.8.2 it changes exactly 16 package entries:

  • 13 Babel entries: add @babel/helper-globals@7.29.7; update code-frame, generator, helper-module-imports, helper-module-transforms, helper-plugin-utils, helper-string-parser, helper-validator-identifier, parser, SystemJS transform, template, traverse, and types to 7.29.7;
  • 3 mapping entries: @jridgewell/gen-mapping 0.3.8→0.3.13, @jridgewell/trace-mapping 0.3.25→0.3.31, and remove the now-unused @jridgewell/set-array@1.2.1.

Any wider result must be investigated rather than accepted mechanically.

Acceptance criteria

  • The RED test demonstrably fails on exact main before the lock change.
  • package.json is byte-identical and no dependency/override is added.
  • The lock diff is exactly the reviewed 16-node closure above.
  • The installed graph has exactly one patched SystemJS transform and the unchanged preset parent/range; npm ls introduces no new graph error.
  • The safe module string-name regression produces computed string-property syntax under the installed plugin.
  • Fresh Node 20 production audit falls from 3 high/1 low to 2 high/1 low and no longer contains GHSA-fv7c-fp4j-7gwp. The separate brace-expansion, minimatch, and Babel-core findings remain explicitly unresolved and are not called safe.
  • Clean before/after optimized build manifests record file count, total bytes, and aggregate per-file SHA-256; any difference is reviewed and explained.
  • Focused dependency tests and the full local verification gates pass.
  • SECURITY.md, GITHUB_ISSUES.md, GITHUB_ISSUE_SLICES.md, and OPERATIONS_RUNBOOK.md record the exact outcome, residual findings, and source-only deployment limits.
  • Independent adversarial review finds no authorization, App Check, input-bound, PII/secret, idempotency, impossible-transition, lock-topology, or production-fallback issue.
  • PR and closure evidence distinguish source changed, tests passed, merged, website unpublished/unverified, Firebase undeployed, providers unchanged, and production behavior unverified.

Migration and rollback

No schema, data, account, payment, Firebase, provider, or runtime migration. Roll back only by a separately reviewed lockfile revert after reassessing the reopened high-severity advisory; never silently restore the vulnerable resolution.

Out of scope

  • Broad Babel/preset modernization.
  • firebase-tools or Java changes.
  • brace-expansion, minimatch, Babel-core, Functions, or other audit findings.
  • React, application, Firebase Function, Rules, workflow, or officer-procedure behavior changes.
  • Production data, live provider calls, Firebase deployment, or website publication.

Claim protocol

Creation is not a claim. Before editing implementation files, assign the issue, create/push a branch from exact main, post a timestamped CLAIMED by <canonical agent> at <UTC>; branch <branch>; base <sha> marker, re-read it, and move status:ready to status:in-progress. Earliest valid claim wins. This is one atomic child of #105 / SUPPLY-001; the parent tracker remains open.

Metadata

Metadata

Assignees

Labels

area:ciContinuous integration and deploymentarea:webWeb application and hostingpriority:P0Launch blocker or urgent security risksize:SSmall focused issuetype:reliabilityReliability and recoverytype:securitySecurity or privacy boundarytype:testingTest infrastructure and quality gates

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions