Handle mixed-case URLs in Windows command safety (#30879)

## Summary

- recognize embedded HTTP(S) URL prefixes case-insensitively in Windows
dangerous-command detection
- add regression coverage for uppercase and mixed-case schemes inside
`Start-Process` invocations

## Why

PowerShell and URL parsing treat schemes case-insensitively, but the
pre-parser only searched for lowercase `http://` and `https://`. When a
URL appeared in the same shlex token as surrounding PowerShell syntax,
such as `Start-Process('HTTPS://example.com');`, the prefix was not
stripped and the command was incorrectly classified as not dangerous.

Validated with the scoped `codex-shell-command` suite (138 tests) and a
direct classifier reproduction that failed before the change and passed
afterward.
This commit is contained in:
Charlie Marsh
2026-07-07 17:50:39 -04:00
committed by GitHub
parent 172ab264bd
commit 9deb4f9c86

View File

@@ -315,9 +315,10 @@ fn looks_like_url(token: &str) -> bool {
Lazy::new(|| Regex::new(r#"^[ "'\(\s]*([^\s"'\);]+)[\s;\)]*$"#).ok());
// If the token embeds a URL alongside other text (e.g., Start-Process('https://...'))
// as a single shlex token, grab the substring starting at the first URL prefix.
let urlish = token
let lowercase_token = token.to_ascii_lowercase();
let urlish = lowercase_token
.find("https://")
.or_else(|| token.find("http://"))
.or_else(|| lowercase_token.find("http://"))
.map(|idx| &token[idx..])
.unwrap_or(token);
@@ -434,6 +435,19 @@ mod tests {
])));
}
#[test]
fn powershell_start_process_mixed_case_urls_are_dangerous() {
for script in [
"Start-Process('HTTP://example.com');",
"Start-Process('hTtPs://example.com');",
] {
assert!(
is_dangerous_command_windows(&vec_str(&["powershell", "-Command", script])),
"{script}"
);
}
}
#[test]
fn powershell_start_process_local_is_not_flagged() {
assert!(!is_dangerous_command_windows(&vec_str(&[