Skip to content

fix(security): reject file:// URLs that name a host in workspace I/O - #9

Merged
ra-co88 merged 2 commits into
developfrom
fix/unc-path-guard
Oct 12, 2026
Merged

ra-co88 merged 2 commits into
developfrom
fix/unc-path-guard

Conversation

@ra-co88

@ra-co88 ra-co88 commented Oct 11, 2026

Copy link
Copy Markdown
Owner

SEC-2 file:// netloc hardening at the HTTP surface.

workspace._workspace_io_path now rejects file:// URLs whose netloc is
anything other than a bare drive letter — a UNC host
(file://server/share/x) or a backslash path (file://C:\\Users\\x) fails
closed with 403 instead of being resolved and containment-tested against a
host-layout-dependent allowlist.

Exploitability check on the shipped 1.0.2b7+ra.1:

  • UNC host → resolves to /share/x (no drive): the existing allowlist already
    denies it, so this half is defense in depth.
  • Backslash form → the whole remainder lands in netloc, path is empty →
    resolves to . (the server process cwd). That is a host-absolute
    interpretation of a user-controlled query parameter landing on the server
    working directory: exploitable, not defense in depth. That drives the
    +ra.2 hotfix.

Tests: hostile host forms assert 403; file://C:/... (the two-slash shape
Windows CI builds, where urlparse puts the drive in netloc) asserts it is
NOT rejected as a host.

Companion PR: chore/version-sync-gate (release version-sync test + Makefile
force-run + publish SKILL fork note). This PR is the security half only.

SEC-2 file:// netloc hardening. workspace._workspace_io_path now
rejects file:// URLs whose netloc is anything other than a bare drive
letter. urlparse puts the drive in netloc for the two-slash form
Windows CI builds (file://C:/...), and that is the only netloc we
accept. Anything else fails closed with 403 instead of being resolved
and tested against a host-layout-dependent allowlist:

- file://server/share/x.txt (UNC) would otherwise resolve to the local
  path /share/x.txt
- backslash paths put the whole remainder in netloc and used to
  collapse to the process cwd

Regression tests assert the hostile forms -> 403, and assert that
file://C:/... is NOT rejected as a host so the shape Windows actually
sends keeps working.

Guard only -- the version-sync gate lives in the companion
chore/version-sync-gate PR.
On Windows, file://C:/Users/... passes _safe_io_path and the backend
containment check raises PermissionError, which read_file did not catch
(500). Map it like download_file/read_doc. The bare-drive test now asserts
the host rejection did not fire (message check) instead of status != 403,
because the outcome is platform-dependent: 404 on Linux, 404 via the
containment layer on Windows.
@ra-co88
ra-co88 merged commit 85422eb into develop Oct 12, 2026
4 of 6 checks passed
@ra-co88
ra-co88 deleted the fix/unc-path-guard branch October 19, 2026 20:40
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.

2 participants