diff --git a/docs/EVOLUTION_STATUS.md b/docs/EVOLUTION_STATUS.md index 8adf1b79140..5df251ff86a 100644 --- a/docs/EVOLUTION_STATUS.md +++ b/docs/EVOLUTION_STATUS.md @@ -198,7 +198,11 @@ images are digest-pinned. Measured on the release tree with `npm audit --omit=de | Tree | info | low | moderate | high | critical | | ------------------- | ---- | --- | -------- | ----- | -------- | | Root production | 0 | 0 | 0 | **0** | **0** | -| Electron production | 0 | 0 | 0 | **1** | **0** | +| Electron production | 0 | 0 | 0 | **0** | **0** | + +Re-measured on 2026-09-19 after the `js-yaml` fix below. The Electron tree is also clean in the +full run that includes dev dependencies (`npm audit --package-lock-only`: 0 across every +severity). The verification round caught this claim being stale: a second, higher advisory on `adm-zip` (GHSA-7q85-xj36-vmfc, high, fixed in 0.6.1) had appeared in the root production tree through the @@ -206,9 +210,13 @@ optional `@huggingface/transformers` → `onnxruntime-node` chain, while the reg was none. It was fixed rather than re-documented — a lockfile-only bump to 0.6.1 inside the existing `^0.6.0` override, a three-line diff that took root production from `high: 1, moderate: 2` to zero. -The remaining `high` is accepted as residual: `js-yaml` 4.3.1, register id **R-10**, reachable only -from the Electron shell's update-check chain. It is not in the container image, the npm package or -the server runtime, and clearing it needs an Electron lockfile refresh that is out of scope here. +The last remaining `high` was then cleared the same way rather than carried: `js-yaml` 4.3.1, register +id **R-10**, reachable only from the Electron shell's update-check chain (`electron-updater` 6.8.9 → +`js-yaml`), never in the container image, the npm package or the server runtime. A lockfile-only bump +to 4.3.2 inside the existing `^4.2.0` override took Electron production from `high: 1` to zero, and +the shared hoisted copy meant it cleared the dev-tree `electron-builder` entries too. `package.json` +is unchanged; the diff is five lines of `electron/package-lock.json`. **No advisory is accepted as +residual in either shipped production tree.** ## Phase 11: documentation @@ -265,7 +273,7 @@ have been irreversible or contract-breaking in a patch release. | The in-memory decision store grows under a burst of wide candidate pools | Low | Memory pressure on the server process | Bounded by count, by a 32 MB byte budget and by a 30-minute TTL; candidates are compacted before storage | | An operator enables SLO webhook alerts and gets paged by a breach that is really an idle provider | Low | Alert fatigue | An idle open breaker reports `insufficient_data` instead of breaching; alert state resets when alerting is toggled | | A routing decision id is guessed and read by another caller | Low | Disclosure of routing metadata (never prompts or credentials) | Management auth on the lookup route; identical `404` for unknown and malformed ids | -| The Electron `js-yaml` advisory (R-10) is exploited | Low | Build-chain only; no server or dashboard exposure | Recorded in the vulnerability register; a lockfile-only refresh is planned | +| The Electron `js-yaml` advisory (R-10) is exploited | Closed | Build-chain only; no server or dashboard exposure | **Fixed** 2026-09-19: lockfile-only bump to `js-yaml` 4.3.2; Electron production audit is now clean | | The 151 OpenAPI-covered routes without a contract test drift from the served contract | Medium | Documentation and SDKs disagree with the server | The governance baseline tracks them and cannot grow; the SDK drift test covers the documented surface | | A gate or test run without isolated `DATA_DIR`/`HOME` touches a developer's real database | Medium | Unintended migration on a production install | Every command in this release exported isolated `DATA_DIR`, `HOME`, `USERPROFILE` and `APPDATA`; `tests/_setup/isolateDataDir.ts` enforces it in the test runner | @@ -274,7 +282,9 @@ have been irreversible or contract-breaking in a patch release. - The **workspace and budget hierarchy** is designed but not implemented (Phase 8 ADR). - **151 routes** are covered by OpenAPI but have no contract test referencing them yet; the governance baseline tracks them. -- The **`js-yaml` R-10** advisory in the Electron chain is accepted as residual. +- ~~The **`js-yaml` R-10** advisory in the Electron chain is accepted as residual.~~ Fixed + 2026-09-19 — `js-yaml` 4.3.2, lockfile only. No advisory is accepted as residual in either + shipped production tree. - A live **latency budget** is not enforced per candidate; the contract documents exactly what live traffic does enforce, and the remaining work depends on decomposing `open-sse/services/combo.ts`. - Accessibility was gated on login, dashboard, providers and settings; combos, logs and onboarding diff --git a/docs/security/VULNERABILITY_REGISTER.md b/docs/security/VULNERABILITY_REGISTER.md index 3cb47fd81b7..5972696bb12 100644 --- a/docs/security/VULNERABILITY_REGISTER.md +++ b/docs/security/VULNERABILITY_REGISTER.md @@ -42,7 +42,9 @@ Result, as measured on 2026-09-14: this run and made the same tree report `high: 1` without any dependency changing. - Root dev-only: 4 high advisories (2 × extract-zip, js-yaml, smol-toml), 0 critical. - Electron app (`electron/package-lock.json`): 1 high advisory in a production dependency - (R-10). + (R-10). **This statement expired.** R-10 was fixed on 2026-09-19 — see the + [Electron re-measurement](#electron-re-measurement--2026-09-19); that tree now reports no + advisory of any severity. ## Re-measurement — 2026-09-19 @@ -61,9 +63,11 @@ Result, as measured on 2026-09-14: **Current result: the root production tree reports no advisory of any severity.** Both adm-zip records (R-01 and R-11) are closed by the fix; the remaining 7 entries in the full run -are the dev-only records R-02 … R-09. The Electron app lockfile is unchanged (R-10 still open). +are the dev-only records R-02 … R-09. The Electron app lockfile was still unchanged at this +point (R-10 open); it was fixed later the same day — see the +[Electron re-measurement](#electron-re-measurement--2026-09-19). -The fix is item 2 of the [Proposed dependency PR](#proposed-dependency-pr-not-applied), applied +The fix is item 2 of the [dependency PR items](#dependency-pr-items), applied as a lockfile-only change: `npm update adm-zip --package-lock-only --ignore-scripts` moved `adm-zip` 0.6.0 → 0.6.1 inside the existing root override `^0.6.0`. `package.json` is unchanged and the whole diff is three lines of `package-lock.json` (version, resolved, @@ -71,6 +75,49 @@ integrity). `node_modules` was not touched. Verified afterwards: `tests/unit/onnxruntime-single-copy.test.ts` (2/2 pass, the transformers/onnxruntime version pair is intact) and `npm run check:lockfile` (OK). +## Electron re-measurement — 2026-09-19 + +- Toolchain: Node v24.16.0, npm 11.13.0. Electron lockfile: 285 packages audited. +- Trigger: R-10 was the last high advisory left in a shipped production tree, and it was the + only record still described as an accepted residual. + +| Run | Command | Critical | High | Moderate | Low | Total | +| ------------------------------ | ------------------------------------------ | -------- | ----- | -------- | --- | ----- | +| electron prod (before the fix) | `npm audit --omit=dev --package-lock-only` | 0 | **1** | 0 | 0 | 1 | +| electron prod (after the fix) | `npm audit --omit=dev --package-lock-only` | 0 | 0 | 0 | 0 | 0 | +| electron full (after the fix) | `npm audit --package-lock-only` | 0 | 0 | 0 | 0 | 0 | +| root prod (unchanged by this) | `npm audit --omit=dev --package-lock-only` | 0 | 0 | 0 | 0 | 0 | + +**Current result: both shipped production trees report no advisory of any severity, and the +Electron tree is clean in the full run too** — the dev-only `app-builder-lib`, `builder-util` +and `dmg-builder` copies deduplicate onto the same hoisted `js-yaml`, so the single bump +cleared them as well. + +The fix is item 1 of the [dependency PR items](#dependency-pr-items), applied +as a lockfile-only change: `npm update js-yaml --package-lock-only --ignore-scripts` moved +`js-yaml` 4.3.1 → 4.3.2 inside the existing Electron override `^4.2.0` (and inside +`electron-updater`'s declared `^4.1.0`). `electron/package.json` is unchanged — the override +already permitted the fixed version, so no new `overrides` entry was needed. `node_modules` was +not touched. + +The diff is five lines of `electron/package-lock.json`: three for `js-yaml` (version, resolved, +integrity) and two where npm synchronised the lockfile's own `version` field from the stale +`3.8.51` to the `3.8.54` already declared in `electron/package.json`. No other package changed +version. + +Verified afterwards: `npm run check:lockfile` (OK) and the two commands behind +`audit:electron` — `npm --prefix electron audit --audit-level=critical` and +`--audit-level=high` — both exit 0, so the non-blocking high-severity warning that this script +used to print is gone. The `audit:electron` script itself was not run end to end on this +machine: its `(cmd || echo)` shell form is POSIX syntax that cmd.exe rejects before npm audit +runs, which is a pre-existing Windows-only limitation of the script and unrelated to this +change. + +A full `electron-builder` packaging run was **not** executed here — it needs a download of the +Electron binaries and a code-signing environment this worktree does not have. What was checked +instead: `electron/package.json` parses, its `build` block is byte-for-byte unchanged by this +commit, and the only file this commit touches under `electron/` is `package-lock.json`. + ## Summary | ID | Advisory | Package | npm severity | Tree | Installed | First fixed | Action | @@ -84,7 +131,7 @@ pair is intact) and `npm run check:lockfile` (OK). | R-07 | GHSA-8cw4-87c7-c6xx | csv-parse | moderate | root dev | 7.0.1 | 7.0.2 | Lockfile refresh proposed | | R-08 | GHSA-6w3j-5fw6-r9vr | joi | low | root dev | 18.2.3 | 18.2.5 | Lockfile refresh proposed | | R-09 | GHSA-gg4h-3hg2-grpc | joi | low | root dev | 18.2.3 | 18.2.4 | Lockfile refresh proposed | -| R-10 | GHSA-2883-xcg3-v3hh | js-yaml | high | electron app production | 4.3.1 | 4.3.2 | Lockfile refresh proposed (priority) | +| R-10 | GHSA-2883-xcg3-v3hh | js-yaml | high | electron app production | 4.3.2 | 4.3.2 | **Fixed** 2026-09-19 (lockfile only) | | R-11 | GHSA-7q85-xj36-vmfc | adm-zip | high | root production (optional) | 0.6.1 | 0.6.1 | **Fixed** 2026-09-19 (lockfile only) | Propagation-only entries (no advisory of their own): `@huggingface/transformers` and @@ -99,7 +146,7 @@ or `electron/package-lock.json`). This phase runs against a shared `node_modules not regenerate lockfiles or mix dependency upgrades with other changes. The declared ranges in the lockfiles show that each fixable record resolves by refreshing lock entries within the existing ranges and overrides, with no `package.json` edit. See -[Proposed dependency PR](#proposed-dependency-pr-not-applied). +[dependency PR items](#dependency-pr-items). ## Records @@ -311,15 +358,20 @@ existing ranges and overrides, with no `package.json` edit. See ### R-10 — js-yaml: merge-key CPU exhaustion (Electron app production tree) -- **Package:** `js-yaml` 4.3.1 (`electron/package-lock.json`, `node_modules/js-yaml`, not - marked dev). +**Status: fixed 2026-09-19** (lockfile only). `js-yaml` 4.3.1 → 4.3.2 in +`electron/package-lock.json`. The Electron production tree now reports no advisory of any +severity. Details below describe the advisory as it stood before the fix. + +- **Package:** `js-yaml` 4.3.2 (`electron/package-lock.json`, `node_modules/js-yaml`, not + marked dev). Was 4.3.1 before the fix. - **Advisory:** GHSA-2883-xcg3-v3hh / CVE-2026-84375 — high, CVSS 7.5, CWE-400/CWE-407, published 2026-09-08. This is the same advisory as R-04, recorded separately because it ships in a different artifact. - **Dependency path:** Electron app dependency `electron-updater` 6.8.9 (declared - `^6.8.9` in `electron/package.json`; it declares `js-yaml ^4.1.0`) → `js-yaml` 4.3.1. The + `^6.8.9` in `electron/package.json`; it declares `js-yaml ^4.1.0`) → `js-yaml`. The build-only packages `app-builder-lib`, `builder-util` and `dmg-builder` 26.15.3 (dev) - resolve the same copy. + resolve the same copy, so the single hoisted entry served both trees and one bump cleared + both. - **Affected versions:** `>=4.0.0 <4.3.2`. - **Fixed version:** 4.3.2. - **Real exploitability in OmniRoute:** low. @@ -332,19 +384,20 @@ existing ranges and overrides, with no `package.json` edit. See - This does not affect the npm package or the Docker image. - **Impact if exploited:** the Electron main process hangs or spikes CPU during an update check, a denial of service of the desktop app. -- **Action taken:** none in code. Proposed: refresh the `electron/package-lock.json` entry to - 4.3.2 (allowed by `^4.1.0`); this is the only high advisory in a shipped production tree. -- **Justification:** exploitation needs control of the release feed. The fix is a lockfile - change in a separate lockfile, out of scope for this phase. `audit:electron` blocks only on - critical, so it reports this as a warning. +- **Action taken:** fixed on 2026-09-19. `npm update js-yaml --package-lock-only +--ignore-scripts` refreshed the `electron/package-lock.json` entry to 4.3.2, allowed by both + `electron-updater`'s declared `^4.1.0` and the existing `^4.2.0` override in + `electron/package.json`. No `package.json` change and no new override were needed. + `audit:electron` no longer emits its non-blocking high-severity warning. -## Proposed dependency PR (not applied) +## Dependency PR items This should be a dedicated PR that changes only `package-lock.json` and `electron/package-lock.json`, with no mass upgrade: -1. `electron/package-lock.json`: `js-yaml` 4.3.1 → 4.3.2 (R-10), within `^4.1.0`. Do this - first: it is the only high advisory in a shipped production tree. +1. ~~`electron/package-lock.json`: `js-yaml` 4.3.1 → 4.3.2 (R-10), within `^4.1.0`.~~ + **Applied 2026-09-19** — lockfile only, via `npm update js-yaml --package-lock-only +--ignore-scripts`. It was the last high advisory in a shipped production tree. 2. ~~`adm-zip` 0.6.0 → 0.6.1 (R-01), within the root override `^0.6.0`.~~ **Applied 2026-09-19** — lockfile only, via `npm update adm-zip --package-lock-only`. It also closes R-11, the high advisory that appeared later on the same package. diff --git a/electron/package-lock.json b/electron/package-lock.json index 3a09058e08a..02dce083982 100644 --- a/electron/package-lock.json +++ b/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "omniroute-desktop", - "version": "3.8.51", + "version": "3.8.54", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "omniroute-desktop", - "version": "3.8.51", + "version": "3.8.54", "license": "MIT", "dependencies": { "electron-updater": "^6.8.9" @@ -2234,9 +2234,9 @@ } }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "funding": [ { "type": "github",