fix(workspace-fs): confine host-service filesystem ops to the workspace root (GHSA-6223-9p9j-gwf2, GHSA-9v86-rjhr-mqw6, GHSA-rg8v-v9gh-vwpq)

Merged
KI
1mo ago
+350-68

Summary

Confirms and fixes three advisories (rg8v duplicates 9v86): host-service filesystem.readFile/listDirectory/getMetadata could read arbitrary absolute paths, and movePath/copyPath could escape the workspace root via symlink ancestors.

Fix (well-factored)

One shared confinement gate (resolve realpath, assert it stays within the workspace root) applied across read/list/getMetadata/move/copy, so a new fs op is confined by default.

Proof

Exploit PoC 0/6 → 6/6 blocked; path-confinement.test.ts 5/7 → 12/0; workspace-fs 158 pass; desktop typecheck clean; biome clean. One failing test verified pre-existing on a clean tree.
Write-up: https://app.superset.sh/page/p1-a-host-service-filesystem-path-confinement-7uq4tb

Reviewer decision

The read-confinement half touches an existing test that pins "reads are host-wide" as intended policy — flagged for a human trust-model call, not decided here.

Merge note

Squash-merge only (earlier commits held local repro artifacts, now untracked).


Summary by cubic

Confines readFile, listDirectory, getMetadata, movePath, and copyPath to the workspace root, closing GHSA-6223-9p9j-gwf2, GHSA-9v86-rjhr-mqw6, and its duplicate GHSA-rg8v-v9gh-vwpq. Previously the read ops accepted any absolute path and move/copy only checked lexical containment, so a symlinked ancestor inside the worktree could escape it. All five ops now resolve the real path and reject anything outside the root.

Breaking change

  • Reads are no longer host-wide: a workspace-scoped read that points outside the root now throws. This reverses the old documented policy; browseHost and statPath remain the host-wide escape hatches. A few tests that pinned the old read policy were inverted.

Summary by CodeRabbit

  • Bug Fixes
    • Workspace file operations are now confined to the workspace, including reads, directory listings, metadata checks, writes, moves, and copies.
    • Attempts to access files outside the workspace or through symlinks that escape it are rejected. In-workspace files and symlinks can still be accessed according to the operation.