Skip to content

fix(runtimes): make path guards and binary lookup correct on Windows#503

Merged
Xoshbin merged 3 commits into
Xoshbin:mainfrom
dose-dot-dev:fix/runtimes-windows-path-guards
Jul 14, 2026
Merged

fix(runtimes): make path guards and binary lookup correct on Windows#503
Xoshbin merged 3 commits into
Xoshbin:mainfrom
dose-dot-dev:fix/runtimes-windows-path-guards

Conversation

@dose-dot-dev

Copy link
Copy Markdown
Contributor

First slice of fixing the 38 Windows test failures that became visible once #499 made cargo test loadable on Windows (context in #498). Starting here because two of the three are product bugs in security guards, not test issues.

The bugs

Path::is_absolute() on Windows requires a drive prefix and a root — Path::new("/etc").is_absolute() is false. Two guards relied on it:

  • validate_runtime_name accepted "/etc" on Windows. It also accepted drive-prefixed names in both forms — and PathBuf::join replaces the entire base path when joining anything with a drive prefix, so a hypothetical name like C:evil wouldn't land under the runtimes root at all.
  • extract_tar_gz's tar-slip guard accepted entries like /tmp/evil on Windows (the .. half of the check was fine). Exploitability was already limited because unpack_in strips a leading / itself, but the explicit up-front guard exists to be stricter than that fallback — and on Windows it wasn't.

The fix

  • validate_runtime_name: reject on has_root() (true for /etc and \etc on Windows, and for /etc on Unix) or any Component::Prefix (catches C:\evil and drive-relative C:evil).
  • extract_tar_gz: the ParentDir + is_absolute pair becomes one stricter predicate — any component that is not Normal/CurDir rejects the entry (covers .., rootful, and drive-prefixed in one). ./-prefixed entries, common in tarballs, stay accepted.
  • Behavior on Unix is unchanged for every input the old code rejected; the new code only rejects more (Windows-specific forms).

Test changes

  • ensure_reports_needs_download_again_after_remove fixture now writes binary_file_name("bun") instead of a literal "bun" — the lookup expects bun.exe on Windows (third of the three failures).
  • New #[cfg(windows)] regression tests: validate_runtime_name rejecting C:\evil / C:evil / \etc, and extract_tar_gz rejecting a drive-prefixed entry.

Verification

  • Windows 11: cargo test runtimes green, including the previously-failing three and the new Windows-only tests.
  • Linux (WSL): full cargo test — 2856 passed; the one failure is the known WSL environment issue (fs_watcher under max_user_instances=128, reproduces on clean main). cargo clippy --all-targets -- -D warnings and cargo fmt clean.

🤖 Generated with Claude Code

Two of the guards used Path::is_absolute(), which on Windows requires a
drive prefix AND a root — so unix-absolute paths slipped through:

- validate_runtime_name accepted "/etc" (and drive-prefixed names like
  "C:evil", which Path::join lets replace the runtimes root entirely).
  Reject on has_root() or any Prefix component instead.
- extract_tar_gz's tar-slip guard accepted entries like "/tmp/evil" on
  Windows. Replace the ParentDir+is_absolute check with a single
  components guard: any component that is not Normal/CurDir (ParentDir,
  RootDir, or a drive Prefix) rejects the entry. "./"-prefixed entries
  stay accepted.

Also fix the ensure_reports_needs_download_again_after_remove fixture to
write binary_file_name("bun") — the lookup expects bun.exe on Windows.

These three tests were among the 38 Windows failures that became visible
once Xoshbin#499 made cargo test loadable on Windows (see Xoshbin#498). New regression
tests cover the drive-prefixed/rootful forms on Windows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGJAx66y29o33szDvVYTBH

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances security and path traversal guards across platforms, particularly addressing Windows-specific path behaviors. It updates the tar-slip guard in extract_tar_gz to reject any non-normal or non-current directory components, and improves validate_runtime_name to reject absolute, rootful, or drive-prefixed paths. The review feedback correctly identifies a critical vulnerability where . is accepted as a valid runtime name, which could lead to the accidental deletion of the entire runtimes directory, and suggests restricting the validation to a single normal component along with adding corresponding test coverage.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread asyar-launcher/src-tauri/src/runtimes/mod.rs Outdated
Comment thread asyar-launcher/src-tauri/src/runtimes/mod.rs Outdated
Gemini review caught a pre-existing hole the has_root/Prefix check kept:
"." passes validation, and remove_from_root(root, ".") resolves to the
runtimes root itself — remove_dir_all would delete every installed
runtime. Require exactly one Component::Normal instead, which rejects
".", "./x", separator-containing names, rootful and drive-prefixed paths
in one predicate. New regression test covers "." and multi-component
names.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGJAx66y29o33szDvVYTBH
@Xoshbin Xoshbin merged commit 2f5be1b into Xoshbin:main Jul 14, 2026
1 check 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.

2 participants