Skip to content

SUPPLY-001D4 — Patch critical websocket-driver in the root production dependency tree #310

Description

@daliu

Officer impact: None — this child patches and verifies one root transitive dependency. It does not change a member or officer screen, task, permission, collected field, payment, or live service.

Officer documentation: None — no current officer procedure, diagram, approval, incident, backup, or recovery behavior changes.

Deployment evidence: None at issue creation. Closure must distinguish source, tests, merge, website publication, Firebase deployment, outside-provider configuration, production data, and live behavior. A lockfile merge or green CI run is not deployment.

Problem

On exact released main fcb7f77cd1c26e28f785416249f7e80c5ba71757, the committed root dependency tree contains one hoisted non-development websocket-driver@0.7.4 node.

Production path:

firebase@11.10.0 -> @firebase/database@1.0.20 -> faye-websocket@0.11.4 -> websocket-driver >=0.5.1

The same node also satisfies the development path:

webpack-dev-server@4.15.2 -> sockjs@0.3.24 -> websocket-driver ^0.7.4

Both ranges admit 0.7.5. GHSA-xv26-6w52-cph6 is critical, affects versions below 0.7.5, has no workaround, and describes message corruption through protocol length-header abuse. GHSA-mp7j-qc5w-4988 is a separate moderate resource-limit bypass fixed by the same release.

The current modular application does not import Firebase Realtime Database. Searches of existing optimized builds found no Faye, websocket-driver, or draft-protocol parser signature. That lowers observed reachability but does not justify keeping a known critical node in the production-classified dependency graph or allowing a future import to expose it.

A Node 20.19.5/npm 10.8.2 lock-only simulation changes exactly one package-lock record from 0.7.4 to 0.7.5, with no parent, sibling, dependency, engine, or development-flag change. Fresh verification must confirm that result.

Current dated audit snapshot inherited from exact main before this package-only child:

  • full root audit: 67 affected-package findings — 13 low, 19 moderate, 32 high, 3 critical
  • production-only root audit: 7 — 1 low, 2 moderate, 3 high, 1 critical

The expected result is 66 full findings with 2 critical and 6 production findings with 0 critical, because the single node currently carries both advisories. Report actual fresh results and do not assert mutable audit totals in source tests.

Atomic outcome

  • Regenerate only the root lock resolution needed to install websocket-driver@0.7.5.
  • Keep root package.json unchanged; both parents already admit 0.7.5.
  • Extend the existing dependency-free Node regression with exact committed/installed identity, sole-resolution, and parent-range checks.
  • Add a small public-API draft-75 synthetic length-header regression with a one-byte maxLength. It must fail on 0.7.4 and close deterministically on 0.7.5 without large input or memory pressure.
  • Keep the existing blocking hosted-CI command unchanged because it already runs tests/root-dependency-security.test.js.
  • Add one separately named SUPPLY-001D4/RISK-014 security-ledger row without rewriting the dated headline or historical D1/D3 evidence.
  • Compare clean optimized artifacts before and after because npm classifies this node as production; stop and explain any unexpected difference.

Expected exact identity, to verify rather than assume:

  • version 0.7.5
  • registry URL https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz
  • integrity sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==
  • unchanged dependencies on http-parser-js, safe-buffer, and websocket-extensions
  • exactly one locked and installed websocket-driver copy

Invariants

  • No npm audit fix or npm audit fix --force.
  • No root package.json, workflow, artifact-contract, Functions package, or Functions lock change.
  • No application runtime, Firebase Realtime Database adoption, Firestore Rules, configuration, schema, migration, provider, deployment, production-data, or live-behavior change.
  • No secrets, environment values, customer/member/payment records, provider calls, or production Firebase access in the regression.
  • Registry identity and integrity must be exact, public, and reviewed.
  • The test must use only fixed synthetic request bytes and a tiny configured limit.
  • Use the public websocket-driver API; do not depend on private draft parser internals.
  • Prove a successful draft-75 handshake/open state before supplying the hostile length header.
  • Do not infer website exploitability from npm production classification.
  • Preserve every unrelated worktree change and active claim.

Required proof

Red

  • Against the exact old 0.7.4 install, the identity test rejects the version and the synthetic public-API length-header case remains open instead of closing at the configured bound.
  • Record fresh baseline full and production-only audit results.

Green

  • Clean Node 20/npm install from the committed lock.
  • Focused root dependency regression, including a threshold control that avoids an unconditional-close false positive.
  • Exact npm ls websocket-driver --all.
  • Full and --omit=dev root audits with honest remaining counts and no finding for either websocket-driver advisory.
  • Frontend lint, Jest, TypeScript, diagnostic build, Functions lint/tests, Rules suite, commerce emulator, SPA/workflow/release/readback/artifact tests, and diff check.
  • Fresh clean optimized-build comparison plus an explicit bundle-signature search.
  • Exact lockfile review proving only the intended package record changed.
  • Independent dependency/security, test-contract, and runtime/artifact/scope reviews approve the exact final diff.

Exact owned paths and hunks

  1. package-lock.json — only the npm-generated node_modules/websocket-driver identity record
  2. tests/root-dependency-security.test.js — additive separately named SUPPLY-001D4 constants/helpers/tests only; preserve every SUPPLY-001D3 form-data/hasown hunk
  3. SECURITY.md — one separate SUPPLY-001D4 row under the RISK-014 remediation ledger

Dependencies and coordination

Explicitly out of scope

Do not upgrade Firebase, Firebase CLI, webpack/dev-server, SockJS, Faye, or any major package; import Realtime Database; alter application code; add an override/direct dependency; edit workflows or officer documentation; deploy; configure an outside provider; inspect production data; or accept/time-bound any remaining advisory.

Claim protocol

Creation is not a claim. Before any repository edit: assign the issue, confirm dependencies and active claims again, post CLAIMED by <canonical agent> at <UTC>; branch <branch>; exact base <SHA>, move status:ready to status:in-progress, and push the unique branch. Earliest valid timestamped claim wins.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:ciContinuous integration and deploymentarea:firebaseFirebase services and datapriority: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