From 99e984c1dce6d77ef51cfcc5c4cf7d8af64a0826 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Thu, 9 Apr 2026 15:29:09 -0700 Subject: [PATCH 1/2] fix: DLL hijacking vulnerability in c2patool (CAI-8608) --- Cargo.lock | 1 + cli/Cargo.toml | 3 +++ cli/src/main.rs | 14 ++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 910bc166b..8d02eff8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,6 +657,7 @@ dependencies = [ "treeline", "url", "wasi 0.14.7+wasi-0.2.4", + "windows-sys 0.59.0", "wstd", ] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d172543af..dc4c6f592 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -51,6 +51,9 @@ etcetera = "0.11.0" reqwest = { version = "0.12.4", features = ["blocking"] } tokio = { version = "1.44.2", features = ["rt", "rt-multi-thread"] } +[target.'cfg(windows)'.dependencies] +windows-sys = { version = "0.59", features = ["Win32_System_LibraryLoader"] } + [target.'cfg(target_os = "wasi")'.dependencies] wasi = "0.14" wstd = "0.5" diff --git a/cli/src/main.rs b/cli/src/main.rs index 53181594a..3d085d493 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -630,6 +630,20 @@ fn print_reader(reader: &Reader, detailed: bool, crjson: bool) -> Result<()> { } fn main() -> Result<()> { + // Harden against DLL hijacking on Windows by removing the current working + // directory from the DLL search path. Without this, Windows' default DLL + // search order includes the CWD, which allows an attacker to place a + // malicious DLL alongside the executable. LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + // restricts the search to: the application directory, System32, and + // directories added via AddDllDirectory/SetDllDirectory — excluding the CWD. + #[cfg(windows)] + // SAFETY: no invariants to uphold; the argument is a valid constant. + unsafe { + windows_sys::Win32::System::LibraryLoader::SetDefaultDllDirectories( + windows_sys::Win32::System::LibraryLoader::LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, + ); + } + let args = CliArgs::parse(); // set RUST_LOG=debug to get detailed debug logging From 9f4f49ead7feedcacf4e8ea7cdfda205e4cb3369 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Fri, 10 Apr 2026 09:50:26 -0700 Subject: [PATCH 2/2] If `SetDefaultDllDirectories` returns 0 (failure), `main()` exits immediately with an error rather than silently continuing with an insecure DLL search path --- cli/src/main.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 3d085d493..86edf084b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -636,12 +636,15 @@ fn main() -> Result<()> { // malicious DLL alongside the executable. LOAD_LIBRARY_SEARCH_DEFAULT_DIRS // restricts the search to: the application directory, System32, and // directories added via AddDllDirectory/SetDllDirectory — excluding the CWD. - #[cfg(windows)] // SAFETY: no invariants to uphold; the argument is a valid constant. + #[cfg(windows)] unsafe { - windows_sys::Win32::System::LibraryLoader::SetDefaultDllDirectories( + if windows_sys::Win32::System::LibraryLoader::SetDefaultDllDirectories( windows_sys::Win32::System::LibraryLoader::LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, - ); + ) == 0 + { + bail!("Failed to set default DLL directories"); + } } let args = CliArgs::parse();