Skip to content

fix(deps): harden dependency security baseline - #40

Merged
Nandem1 merged 3 commits into
mainfrom
hardening/pr9b-dependency-audit
Oct 15, 2026
Merged

Nandem1 merged 3 commits into
mainfrom
hardening/pr9b-dependency-audit

Conversation

@Nandem1

@Nandem1 Nandem1 commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Result

Dependency-file PRs now run the same npm/RustSec policy as scheduled audits and releases, with stable checks npm-dependency-audit and rustsec-dependency-audit. Audit reports and subprocess outcomes are validated before a policy verdict. The only dependency update is the yanked chacha20 0.10.1 resolution to compatible, non-yanked 0.10.2.

Implements FINAL_HARDENING_PLAN §7 P2-F13: dependency PR trigger, stable check names, and a release-invariant regression. Policy thresholds are unchanged: npm runtime moderate+, npm dev/build critical, and all RustSec vulnerabilities block. Other findings remain visible. PR9a's approved SHA 690a2ad347478379db12501885a1d25d26743131 was verified and merged as #39; this branch starts from resulting main 5af60a3b9860c9b5673782bd0e51bc3da186dd60.

Reproduced baseline and finding inventory

Pinned tools: rustc/cargo 1.98.1, Node 22.23.3, bundled npm 10.9.9, cargo-audit 0.22.2. Before and after raw JSON evidence was captured separately for npm audit --json, npm audit --json --omit=dev, and cargo audit --json, plus both policy commands. RustSec database commit: 6aed84668c23d7f535077a9fe918bf1fa0f6a5bc (1,310 advisories). Both npm graphs had zero findings; Cargo had zero vulnerabilities, six unmaintained warnings, one unsound warning, and one yanked warning. No blocking dependency advisory required remediation.

All findings are transitive; every initial finding is listed below. Paths read left to right from the application. Repeated desktop paths through Tao/Wry/WebKit/GTK resolve to the same glib version.

ID Package/version Scope Dependency path Policy/action
RUSTSEC-2024-0370 proc-macro-error 1.0.4 Compiler host only ro-launcher → gtk 0.18.2 → gtk3-macros 0.18.2; gtk → glib 0.18.5 → glib-macros 0.18.5 → proc-macro-error Warning retained
RUSTSEC-2025-0081 unic-char-property 0.9.0 Runtime + build ro-launcher → tauri 2.11.2 / tauri-build 2.6.2 → tauri-utils 2.9.2 → urlpattern 0.3.0 → unic-ucd-ident → unic-char-property Warning retained
RUSTSEC-2025-0075 unic-char-range 0.9.0 Runtime + build Same path → unic-ucd-ident → unic-char-range, also through unic-char-property Warning retained
RUSTSEC-2025-0080 unic-common 0.9.0 Runtime + build Same path → unic-ucd-ident → unic-ucd-version → unic-common Warning retained
RUSTSEC-2025-0100 unic-ucd-ident 0.9.0 Runtime + build Same path → urlpattern → unic-ucd-ident Warning retained
RUSTSEC-2025-0098 unic-ucd-version 0.9.0 Runtime + build Same path → unic-ucd-ident → unic-ucd-version Warning retained
RUSTSEC-2024-0429 / GHSA-wrw7-89jp-8q8g glib 0.18.5 Linux desktop runtime ro-launcher → gtk 0.18.2 → glib; also tauri → tauri-runtime-wry 2.11.2 → tao 0.35.3 / wry 0.55.1 → gtk / webkit2gtk 2.0.2 → glib Unsound warning retained after reachability analysis
yanked:chacha20@0.10.1 chacha20 0.10.1 Locked optional HTTP/3 graph, disabled in product ro-launcher / tauri-plugin-updater → reqwest 0.12.28 [optional http3] → quinn 0.11.11 → quinn-proto 0.11.19 → rand 0.10.2 → chacha20 Precisely update to 0.10.2

Remaining warnings: evidence and remediation risk

proc-macro-error: both parents are procedural macro crates, used for GTK/glib compilation diagnostics rather than linked application code. RustSec identifies abandoned maintenance and no patched version. Published compatible glib-macros 0.18.x and gtk3-macros 0.18.x releases still require proc-macro-error 1.x. Replacing it requires parent source/framework changes; no artificial direct dependency or patch was added. Revisit when compatible parents remove it or a concrete vulnerability is disclosed.

UNIC family: all five warnings originate from urlpattern's Unicode identifier tables. This is present in Tauri's normal and build dependency graphs, not merely a dev dependency. It supports URLPattern parsing for ACL remote capabilities; this repository declares no remote capabilities. RustSec reports maintenance abandonment, not a specific exploit. Registry evidence shows only urlpattern 0.3.0 in the compatible 0.3 line; even tauri-utils 2.9.3 retains ^0.3. tauri-utils 2.10.x moves to urlpattern 0.6 / ICU. That would migrate URL/ACL parsing behavior and the parent framework graph to remove informational warnings, so it is deferred. No safe patch-level family replacement exists within the locked parent contract. Revisit a qualified Tauri update or a new advisory.

glib unsoundness: the affected VariantStrIter iterator methods (next, next_back, last, nth, nth_back) pass an immutable pointer reference to a variadic C out-parameter; optimized builds may then dereference NULL. RustSec and upstream fix confirm the behavior and patched versions >=0.20.0. The locked 0.18.5 source still contains the defect. Production source was searched across the launcher and all 538 registry packages in the resolved metadata: VariantStrIter / array_iter_str occur only in glib's implementation, examples, and tests, with no production caller. The generic Vec<T>::from_variant uses child-value conversion, not this iterator. Direct GTK use only removes the window titlebar. This is evidence of no identified reachable path, not proof that the crate is sound. GTK 0.18.2 and the locked WebKit/Tauri ecosystem require glib 0.18; adding glib 0.20 separately would leave vulnerable 0.18 present and create incompatible Rust wrapper types. No compatible 0.18 patch exists. Retain the warning; reassess immediately if code starts using the iterator, a new reachable path appears, or compatible upstream support lands.

chacha20: only one version is locked. cargo tree --locked --target all --all-features -i chacha20@0.10.1 prints no enabled path; lockfile and cargo metadata establish the optional reqwest HTTP/3 parent chain. rand allows ^0.10.0. The upstream changelog marks 0.10.1 yanked and 0.10.2 fixes the SSE4.1 intrinsic accidentally used in an SSE2 backend; upstream issue #579 and fix #580 explain the UB. cargo update -p chacha20@0.10.1 --precise 0.10.2 changes exactly its version and checksum, with identical dependency edges. Pure Rust, no build.rs/native ABI change, no crypto API migration. In a disposable harness, all 23 published upstream RNG vector/counter/state tests pass with the SSE2 backend explicitly selected.

Before / after

Finding Before After Classification
npm full + runtime 0 advisories 0 advisories Clean under unchanged policy
RustSec vulnerabilities 0 0 Clean under unchanged policy
RUSTSEC-2024-0370 proc-macro-error 1.0.4 warning Same, visible REMAINS — JUSTIFIED NON-BLOCKING
RUSTSEC-2025-0081 unic-char-property 0.9.0 warning Same, visible REMAINS — JUSTIFIED NON-BLOCKING
RUSTSEC-2025-0075 unic-char-range 0.9.0 warning Same, visible REMAINS — JUSTIFIED NON-BLOCKING
RUSTSEC-2025-0080 unic-common 0.9.0 warning Same, visible REMAINS — JUSTIFIED NON-BLOCKING
RUSTSEC-2025-0100 unic-ucd-ident 0.9.0 warning Same, visible REMAINS — JUSTIFIED NON-BLOCKING
RUSTSEC-2025-0098 unic-ucd-version 0.9.0 warning Same, visible REMAINS — JUSTIFIED NON-BLOCKING
RUSTSEC-2024-0429 glib 0.18.5 unsound warning Same, visible REMAINS — JUSTIFIED NON-BLOCKING
yanked chacha20 0.10.1 Non-yanked 0.10.2 FIXED

Audit failure and classification hardening

The original helper could accept exit 1/2/42 plus an empty valid-looking report, incomplete nonempty npm vulnerability entries, duplicate IDs with a later stronger/unknown severity, and absent Cargo warning sections. Nine targeted tests failed against the original implementation before fixes.

A subsequent adversarial configuration probe also reproduced a silent warning disappearance: cargo-audit automatically loads project/user audit.toml, but omits database/yank configuration from JSON. With the original lockfile and [yanked] enabled=false, the first implementation passed while hiding yanked chacha20. The helper now refuses project .cargo/audit.toml and Cargo-home audit.toml, including symlinks and unreadable configuration paths, instead of trusting an unverifiable reduced audit. Two additional subprocess regressions failed before this follow-up and pass after it. No host configuration was changed or removed. The shared command requires upstream defaults and checks report settings as a second defense.

The shared helper now validates npm report v2, object/array shapes, all severity values (including duplicate advisories), package counts, source identity, and meta-vulnerability references. It matches npm's numeric advisory source across full/runtime reports and uses the strongest observed severity. Runtime-only findings still fail closed. Explicit npm include/omit and audit-level arguments prevent inherited config from narrowing the graph or changing expected exit status. Runtime means conservatively frontend dependency participation in bundled WebView assets; no Node runtime or node_modules is shipped. Build tooling can affect build integrity, but its existing critical-only blocking threshold is preserved.

Cargo vulnerability found, count, and list must agree; warning sections and findings must be complete. Reports containing ignores, severity/platform filters, or omitted informational warning categories are rejected. Both tools reject start failures, signal death, invalid JSON/error objects, unexpected exit statuses, and status/report disagreements. Operational stderr errors are rejected, including colorized cargo-audit yank-lookup failures that upstream may emit beside JSON with exit zero. Legitimate npm exit 1 for dev-high findings remains a warning-only success. Cargo findings exit 1 and always block. Warnings still render in stdout, GitHub annotations and step summaries.

Tests execute real subprocess doubles for missing executables, SIGTERM, malformed JSON, operational nonzero empty JSON, and operational stderr. Parser fixtures prove synthetic Rust vulnerability blocks, Rust warnings remain visible, runtime-moderate blocks, dev-high warns, dev-critical blocks, runtime-low warns, meta-vulnerabilities and duplicate identities retain runtime scope. Real disposable vulnerable npm and Cargo lockfiles were also audited by pinned tools: lodash runtime findings block, micromatch/braces dev findings warn (even with conflicting inherited omit/include/audit-level settings), and time's RUSTSEC-2020-0071 blocks. These fixtures never enter the product graph.

F-13 invariants reject a removed PR trigger, missing dependency paths, renamed checks, skipped audit jobs/steps, and hidden command failures. The release workflow remains unchanged and uses exactly the same policy helper as PR/scheduled audits. Weekly schedule and dispatch remain unchanged.

Provenance and scope

No advisory suppression was added: no Cargo/npm ignore, override, patch, severity reduction, continue-on-error, or audit removal. No dependency moved between runtime/dev. No broad cargo/npm update or audit fix was used. Cargo manifests, package.json, package-lock.json, PR9a pins/checker, release workflow, action SHAs and Dependabot are unchanged.

Cargo metadata resolves 538 crates.io packages and six trusted workspace paths; no Git dependency. All 381 third-party npm lock entries have registry.npmjs.org tarballs and integrity. Changed chacha20 checksum matches the crates.io sparse index. Actions remain full-SHA pinned with read-only audit permissions and checkout credentials disabled. Dependabot already covers npm/Cargo/Actions at /; its groups default to version updates, so no security-group redesign or auto-merge was introduced.

Validation

All commands use the pinned tools above. Isolated CARGO_TARGET_DIR starts empty under a disposable maintainer cache directory; normal target/cache contents were preserved.

  • node scripts/check-toolchain-invariants.mjs — PASS.
  • node scripts/check-release-invariants.mjs — PASS.
  • node scripts/dependency-audit-policy.mjs npm — PASS, zero findings.
  • node scripts/dependency-audit-policy.mjs cargo — PASS, seven explicit warnings, zero vulnerabilities.
  • cargo fmt --all -- --check — PASS.
  • cargo build -p ro-inputd -p ro-sessiond --locked — PASS in isolated target.
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings — PASS, isolated target.
  • cargo test --workspace --all-features --locked — PASS, 734 tests passed, nine existing ignored tests; orphan_reparent and Yama harnesses also passed.
  • cargo test -p ro-sessiond --all-features --test orphan_reparent --locked — PASS separately under Yama=1, seven scenarios including 100 repeated cycles.
  • npm ci — PASS, fresh node_modules, zero vulnerabilities.
  • npm test — PASS, 303 tests / 46 files (43 focused audit/release-policy tests).
  • npm run build, npm run lint, npm run format:check, npm run check:design — PASS.
  • Disposable chacha20 upstream RNG suite with --cfg chacha20_backend="sse2" — PASS, 23 tests.
  • git diff --check — PASS.

Desktop smoke is not required for this delta: Tauri, GTK/glib, native libraries and frontend build tooling are unchanged; the only updated crate is pure Rust in a disabled optional graph. The entire Linux workspace compiled and linked from the isolated target. No desktop startup claim or assembled AppImage qualification is inferred from those checks.

Previous F-09/F-01/F-02/F-03/F-04/F-05/F-06/F-07/PR9a regressions remain green in the full gates. This PR does not qualify Wine 7.16, UMU/Proton/game compatibility, N-1 → N updater behavior, flag retirement, or a stable release. Local planning/audit Markdown remains untracked. Leave this PR open and unmerged for independent Opus security review.

Exact-head CI

Final head: b037d62dc0070cc2fae3a62d47c452d5bfd6dffb, two normal commits. Quality CI and both dependency checks passed on that exact SHA. The dependency run visibly renders all seven remaining RustSec warnings and creates seven warning annotations. release-cache is intentionally main-push-only and skipped for this PR. GitHub reports OPEN / CLEAN / MERGEABLE; no merge performed.

@Nandem1
Nandem1 merged commit c5d1dd6 into main Oct 15, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant