webbrowser's WSL browser-open path (try_wsl() in src/unix.rs) escapes only ^ (-> ^^) and & (-> ^&) before invoking cmd.exe /c start <url>, and only & (-> "&") before the powershell.exe Start <url> fallback. |, %, (, ) reach the argv unescaped. The WHATWG URL parser (rust url crate) does not percent-encode | in an http(s) path/query, so any application that passes an attacker-influenced URL to webbrowser::open() on WSL can have it re-parsed by cmd.exe/powershell.exe as a separate command, giving command execution on the Windows host from inside WSL. Verified unchanged on current master as of 2026-10-25. Not the same issue as GHSA-2ph8-5cr8-hr33 (that covered the separate $BROWSER env-template substitution branch; try_wsl() is a different code path and unaffected by that fix). Also distinct from issue #73/#74 (that fixed & truncating the URL display, not metacharacter injection into the shell).
Code (current master, src/unix.rs, try_wsl()):
try_browser!(options, "cmd.exe", "/c", "start", url.replace('^', "^^").replace('&', "^&"))
.or_else(|_| try_browser!(options, "powershell.exe", "Start", url.replace('&', ""&"")))
The URL is passed as a single argv element, but cmd.exe and powershell.exe both re-parse that argv element as a command line once it crosses the WSL interop boundary. Only ^ and & are escaped. | (cmd.exe command separator / PowerShell pipeline operator), % (cmd.exe environment-variable expansion, e.g. %ProgramFiles:~10,1%), and (/) all pass through untouched.
Any URL whose path or query contains a literal | therefore reaches cmd.exe as start <url-with-pipe>, which cmd.exe interprets as start <part-before-pipe> piped into whatever follows the |. Example: cmd.exe /c start https://example.com/a|calc launches calc.exe (or any attacker-chosen binary) on the Windows host.
Impact: any Rust application using this crate's default webbrowser::open() on WSL, where the URL (or any part of its path/query) is influenced by untrusted/remote input, is exposed to command execution on the Windows host -- outside whatever containment the WSL distro itself has. This is a library-level defect; it affects every consumer that calls webbrowser::open() with a non-fully-trusted URL while running under WSL.
Environment: Linux host with WSL interop enabled (/proc/sys/fs/binfmt_misc/WSLInterop containing "enabled"), which is how is_wsl()/guess_desktop_env() route into try_wsl() -- this is testable on a plain Linux box without a real Windows host for the crate-side half below.
url crate, unmodified):
let u = url::Url::parse("https://example.com/a|calc").unwrap();
assert!(u.as_str().contains('|')); // passes -- '|' is not percent-encoded in http(s) pathwebbrowser = "=1.2.4" from crates.io, no source patching, real WSL gate satisfied, logging shim substituted only for the Windows binary target since no Windows host was available to us):
webbrowser::open("https://example.com/a|calc")
-> argv captured at the shim: ["/c", "start", "https://example.com/a|calc"]
od -c of argv[2] shows a literal 0x7c ('|') byte; no '^', '&', or '%' escaping applied to it.
Same result for the powershell.exe fallback (argv: ["Start", "https://example.com/a|calc"]), and for %ProgramFiles:~10,1%- and (calc)-style payloads in the same position (both % and parens also survive unescaped).| as a separator) is documented Windows/cmd.exe behaviour, cited here rather than independently observed on real Windows by us. We believe this closes in a 1-2 minute manual check on any WSL machine: run the two snippets above for real (replacing the logging shim with the actual cmd.exe), with a harmless payload (calc, or notepad) for a Windows-side popup as proof.
Happy to supply the small Rust harness used for steps 1-2 if useful for verification.Command injection / argument injection (CWE-88) leading to arbitrary command execution on the Windows host from within WSL. Impacted: any application or end user running a Rust program that calls webbrowser::open() on WSL with a URL whose path or query is influenced by untrusted or remote-controlled input (e.g. an OAuth authorization_endpoint discovered from a remote server, a deep link, any URL assembled from user/network input). No user interaction beyond the application's own normal "open this URL" action is required.
소스: NVD
무료 취약점 평가
9개 보안 영역에서 클라우드 보안 관행을 평가하여 위험 수준을 벤치마킹하고 방어의 허점을 파악하세요.
맞춤형 데모를 받아보세요
"내가 본 최고의 사용자 경험은 클라우드 워크로드에 대한 완전한 가시성을 제공합니다."
"Wiz는 클라우드 환경에서 무슨 일이 일어나고 있는지 볼 수 있는 단일 창을 제공합니다."
"우리는 Wiz가 무언가를 중요한 것으로 식별하면 실제로 중요하다는 것을 알고 있습니다."