Files
archy/docs/security/2.1-beta-dependency-remediation.md
T

11 KiB

2.1 Beta dependency inventory and remediation

Source dependencies were scanned on 2026-11-09. This work changes source locks and adapts app-gate TLS; it does not build, sign, publish or qualify a release. Individual advisory dispositions are in 2.1-beta-dependency-dispositions.json. Raw receipts are retained under /home/archipelago/Reports/next-release-nine-issues-20261109/.

Scope Initial scan Current scan
Node Rust 37 advisory errors, 2 yanked warnings 3 maintenance notices, no vulnerability/yanked findings; bans pass
Android Rust 3 advisory errors, 1 yanked warning 2 maintenance notices, no vulnerability/yanked findings
Dashboard npm 19 affected package rows, including critical/high 4 low rows from one remaining deepmerge advisory
AIUI pnpm 131 advisory entries 1 low deepmerge advisory
Router npm 9 affected package rows 0
Gashboard pnpm 45 advisory entries 0
App starter npm 0 Unchanged lock; 0
Android Maven 108 resolved release runtime coordinates OSV query returned no advisories
Python runtime/build graph Three requirements pins; esptool 5.6.0 additionally pinned in build scripts Disposable CPython 3.13/Linux x86_64 resolution: 23 packages, zero OSV findings; historical ecdsa dependency removed

Counts from different scanners are not interchangeable. No advisory ignores, blanket waivers or forced npm downgrade were added. The rand duplicate-major rule still rejects a third line; its exact second-major entry follows the patched 0.9.5 version, with 0.8.8 as the other retained line.

Selected versions and migrations

  • Node: anyhow 1.0.104, bytes 1.12.1, libz-sys 1.1.32, negentropy 0.5.3, rand 0.8.8/0.9.5, tar 0.4.46, webpki-roots 1.0.11, rustls 0.23.46, rustls-webpki 0.103.16, reqwest 0.12.28, quick-xml 0.41.0, zip 9.5.0. Futures/hyper parents were updated to remove unmaintained pin-utils.
  • The old rustls 0.21/webpki 0.101/pemfile 1 line is removed. App-gate PEM parsing uses rustls-pki-types. rustls 0.23's with_single_cert verifies certificate/key pairing; the existing mismatch and reload regressions are preserved. The crypto provider is explicitly ring. See the rustls API contract.
  • The existing HTTP/1 websocket adapter is vendored without Rust-source edits; its Hyper features omit unused HTTP/2. This removes h2 0.3 while HTTP/2 clients use patched h2 0.4. Source provenance and MIT license accompany the overlay.
  • Dashboard: DOMPurify 3.4.17, vue-i18n 11.4.18, body-parser 1.20.9, qs 6.17.1, glob 14.0.4, minimatch 11.0.5, serialize-javascript 7.1.4. Narrow overrides update vulnerable transitive ranges instead of accepting npm's suggested PWA downgrade.
  • AIUI: DOMPurify 3.4.17, PDF.js 6.5.438, KaTeX 0.18.11, happy-dom 21.0.4, Vite 7.3.8, Vue 3.5.45 and patched Storybook/Vitest lines. Nested KaTeX, serialization, YAML, UUID and glob dependencies receive scoped overrides.
  • Gashboard's exact pins move to Vite 6.4.6, Vue 3.5.45, Express 4.22.3, Zod 4.6.7 and tsx 4.23.15. Router's compatible patch refresh removes its findings. Android Rust moves Tokio to 1.54.1 and the yanked chacha20 0.10.1 to 0.10.2.

Remaining dispositions

  • instant 0.1.13: no patched release; introduced by the retained Nostr and Reed-Solomon/parking_lot graphs. Migrating those parents must preserve the existing transport overlays.
  • paste 1.0.15: no patched release; retained by Lofty in the node and FIPS dependencies on Android. A maintained macro replacement requires an upstream/overlay change and review.
  • unsafe-libyaml 0.2.11: no patched release. Replacing serde_yaml with another unsafe-libyaml-based fork would retain the finding. A safe parser migration needs manifest/configuration compatibility coverage and is not silently substituted here.
  • deepmerge 4.3.1: no published fix for GHSA-gcqx-w48m-w2h4. It enters the dashboard and AIUI through build tooling. The upstream report and maintainer response disagree about the issue's significance. Keep it visible; no suppression or security-clear claim is made. The next action is a reviewed tool-chain replacement or a narrowly tested source patch, rather than a forced downgrade.
  • The historical ecdsa 0.19.2 timing advisory (GHSA-wj6h-64fc-37mp / CVE-2024-23342, alias PYSEC-2026-1325) is removed from the current Python graph by migrating both build roots to esptool 5.6.0. Its exact dependency declaration uses cryptography. The refreshed 23-coordinate OSV query reports no findings; no ignore/suppression was added. The migration adapts CLI/reset spellings, resource loading, logging and the appointed serial FD import boundary. See source qualification and remaining artifact/serial gates. Existing deployed binaries are not declared remediated by a source change.

Inventory and acceptance

scripts/security-dependency-inventory.py reads the exact workspace, companion, frontend and bundled-app lockfiles; it emits a CycloneDX 1.5 component inventory, input hashes and license-declaration coverage. Supply matching Cargo metadata, the completed Gradle graph and saved public-registry license metadata. Optional --python-report and --python-metadata inputs add a disposable pip dry-run resolution, exact artifact hashes, environment and license provenance. The script rejects missing artifact hashes or a report that disagrees with current source pins, including both esptool build entry points. This is a source inventory, not an installed-image SBOM or license approval.

The updated inventory contains 2,498 unique components, 18 hashed inputs/evidence files and no missing package-level license declarations. The previous 2,477-row, 11-missing-declaration snapshot remains unchanged in security-inventory-final/. The updated source BOM and detailed license rows live in security-inventory-qualified-r3/; their hashes and the previous snapshot are in 2.1-beta-inventory-summary.json. Metadata covers the npm registry, exact package license files and 108 Maven coordinates. The 185 Cargo lock entries absent from the selected metadata graph are explicitly marked as lock-only. Cargo-deny scan claims above concern the selected node/companion feature graphs, not a claim that every dormant upstream workspace feature has been qualified.

The Python report resolves all four exact runtime/build roots and their transitives using a disposable venv with pip install --dry-run --ignore-installed --report; only a disposable source-test venv was installed, with no host or release-environment mutation. All 23 selected artifact hashes were checked; unchanged artifact/license evidence was reused and nine changed/new artifacts were downloaded and reviewed. python-osv-resolved-r2.json records the complete coordinate queries and alias results. This is a point-in-time CPython 3.13.5/Linux x86_64 graph, not a checked-in transitive lock or qualification of other platform markers, embedded vendor libraries or frozen executables.

All 11 previous missing declarations now have exact evidence:

  • The six npm entries resolve to MIT: legacy licenses[].type metadata for buildcheck, cpu-features and ssh2; exact metadata for @rollup/plugin-terser; archive LICENSE files for browser-assert and khroma.
  • auto-value-annotations 1.6.3 and listenablefuture 1.0 inherit Apache 2.0 from their exact Maven parent POM chains. Child/parent URLs and SHA-256 values are retained in maven-license-metadata-r2.json.
  • RNS 1.3.5 and LXMF 1.0.1 declare the custom Reticulum License. LXMF's source archive contains the terms; RNS omits LICENSE from its published wheel and source archive, so the evidence pins its upstream 1.3.5 tag to a commit and hashes that LICENSE. The terms restrict harmful-system use and AI/model-training datasets, and require notice retention. They must not be relabeled MIT. See the upstream RNS terms.
  • PyInstaller 6.21.0's exact COPYING.txt distinguishes GPL terms and a bootloader exception, Apache runtime hooks, and the isolated module's additional MIT option. Its exception does not replace dependency licenses; the versioned licensing documentation and source file define the scope. The resolved hooks-contrib package likewise distinguishes GPL standard hooks from Apache runtime hooks. esptool declares GPL terms and includes additional stub-file notices.

Custom restrictions, file-specific obligations and embedded-vendor/feature scope remain review items despite complete package-level declaration coverage. Four pure inventory regressions passed, covering custom names, resolved transitives, artifact hashes, stale reports and unresolved build-only roots (security-inventory-fixtures-r1.log).

Validation so far includes the listed source scans, successful Gradle dependency resolution, Rust formatting, JSON/YAML lock parsing and whitespace checks. Frozen, script-disabled installs succeeded for the dashboard, Gashboard and Router. Focused dashboard viewer, PiP, paid-file and peer regressions passed 103 tests; three delayed-history tests and five Chromium viewport/playback checks passed separately. These focused results do not replace the integrated frontend suite.

Gashboard's patched API passed its nine existing authentication, access, encrypted history, persistence, parsing and outage-recovery regressions through the fixed ARCHY_TEST_PACKAGE=gashboard scripts/test-backend-isolated.sh target. That target uses private network/PID namespaces and tmpfs data paths; its six runner guard regressions also passed. Receipts: gashboard-api-isolated-r2.log and backend-runner-gashboard-r3.log in the report directory. Rust backend compilation and runtime tests remain reserved for the integrated tree through the same runner; no Rust runtime test was run in this dependency worktree.

Gashboard's API strict TypeScript check and web vue-tsc -b plus Vite source bundle also passed (gashboard-api-types-r1.log, gashboard-web-build-r1.log). Router's strict build initially exposed a missing Bonjour declaration; the exact MIT-licensed @types/bonjour 3.5.13 development dependency fixes it without an any shim. The final Router build passed (router-types-build-r2.log); its production entry and mDNS service were never launched.

Integrated dashboard/AIUI strict types, complete frontend tests and source bundles still need combined qualification, especially PDF rendering/worker loading, math rendering, PWA generation and WebSocket/TLS behavior. The pre-existing Storybook 8 peer range does not advertise Vite 7 support; qualify or migrate that development surface before relying on its build. Maintainer UI/UX UAT remains separate.

A broad Cargo refresh was rejected in favor of targeted package updates; its candidate lock and log remain in the report directory. Failed metadata/lock attempts are retained rather than presented as successful qualification.