From b076a84dc7a09a387fc9c7603b2fdeb462417cc6 Mon Sep 17 00:00:00 2001 From: DuProcess <273172371+DuProcess@users.noreply.github.com> Date: Sun, 12 Jul 2026 22:37:51 -0400 Subject: [PATCH] Reject unsafe Windows update cache segments --- install.ps1 | 9 +++++++++ tests/release_scripts.rs | 3 +++ 2 files changed, 12 insertions(+) diff --git a/install.ps1 b/install.ps1 index 8c9b942..d2c91d8 100644 --- a/install.ps1 +++ b/install.ps1 @@ -276,10 +276,19 @@ function Normalize-PathForCompare($Path) { ) } +function Assert-NoRelativePathSegments($Path) { + foreach ($segment in ($Path -split '[\\/]')) { + if ($segment -eq "." -or $segment -eq "..") { + throw "refusing unsafe update cache path: $Path" + } + } +} + function Assert-SafeUpdateCache($Path) { if (-not $Path) { throw "refusing unsafe update cache path: $Path" } + Assert-NoRelativePathSegments $Path $full = Normalize-PathForCompare $Path $root = Normalize-PathForCompare ([System.IO.Path]::GetPathRoot($full)) $homePath = Normalize-PathForCompare $HOME diff --git a/tests/release_scripts.rs b/tests/release_scripts.rs index ff5fdda..211e193 100644 --- a/tests/release_scripts.rs +++ b/tests/release_scripts.rs @@ -99,6 +99,9 @@ fn installers_refuse_prebuilts_without_checksums() { fn windows_installer_reuses_persistent_source_update_cache() { let ps1 = include_str!("../install.ps1"); assert!(ps1.contains("DOSH_UPDATE_CACHE")); + assert!(ps1.contains("Assert-NoRelativePathSegments($Path)")); + assert!(ps1.contains("Assert-NoRelativePathSegments $Path")); + assert!(ps1.contains("$segment -eq \".\" -or $segment -eq \"..\"")); assert!(ps1.contains("$sourceCache = Assert-SafeUpdateCache $UpdateCache")); assert!(ps1.contains("git -C $sourceCache fetch --depth 1 origin main")); assert!(ps1.contains("git -C $sourceCache checkout -q -B main FETCH_HEAD"));