Sanitize Windows harness prompt arguments#279
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens Windows harness invocation by ensuring user-controlled prompt text is sanitized before being passed as argv when the resolved harness executable is a .cmd shim (invoked via cmd.exe), closing command-injection risk paths.
Changes:
- Apply
sanitize_argv_for_platformto the continuity/resume path incommand_parts_for_harness_with_conversationso theeffective_promptis sanitized before being returned as launch args. - Make
sanitize_argv_for_platformpub(crate)for reuse across the crate. - Update
pty_runner::stream_claude*to build an ownedVec<String>, appendprompt, sanitize the full argv, and pass it viaCommand::args(removing the prior unsanitized.arg(prompt)).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| crates/coven-cli/src/harness.rs | Sanitizes the effective prompt for the continuity/resume branch and exposes the sanitizer for crate-wide reuse. |
| crates/coven-cli/src/pty_runner.rs | Ensures stream-mode Claude invocation sanitizes the appended prompt before spawning on Windows. |
Comments suppressed due to low confidence (1)
crates/coven-cli/src/harness.rs:551
- On Windows, this sanitizer injects surrounding double-quotes into the argument value and escapes embedded quotes as
\\". When the resolved harness is a.cmdshim,std::process::Commandwill build a cmd.exe command line and may backslash-escape these quotes, but cmd.exe does not treat backslashes as an escape character. This can break tokenization and potentially re-enable cmd metacharacter interpretation for user-controlled prompt text.
Safer approach: avoid adding quotes into the arg value and instead caret-escape cmd.exe metacharacters (including ") so cmd.exe receives the intended literal text.
pub(crate) fn sanitize_argv_for_platform(args: Vec<String>) -> Vec<String> {
// Characters that cmd.exe treats as special even inside double quotes
// when the outer caller is cmd.exe itself (i.e. when running a .cmd shim).
const CMD_METACHARACTERS: &[char] = &['&', '|', '<', '>', '^', '%', '!'];
args.into_iter()
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f3d954c to
66a8bd8
Compare
66a8bd8 to
7e6aa3b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
.cmdshim executables (e.g. fromspawn_executable_for_platform), which are invoked throughcmd.exeand therefore require metacharacter neutralization to avoid shell interpretation of user-controlled prompt text..cmdshim is executed.Description
sanitize_argv_for_platformto the conversation-continuity (resume) branch incrates/coven-cli/src/harness.rsso theeffective_promptis sanitized before returning launch args.sanitize_argv_for_platformpub(crate)so it can be reused across the crate.crates/coven-cli/src/pty_runner.rs'sstream_claude*path to construct an ownedVec<String>, append theprompt, callcrate::harness::sanitize_argv_for_platform, and pass the sanitized args toCommand::args(removing the prior unsanitized.arg(prompt)).Testing
cargo fmtandgit diff --check, both succeeded.cargo test -p coven-cli claude_resume_hint_attaches_resume_flag_in_print_modepassed.cargo test -p coven-cli stream_claude_forwards_jsonl_and_returns_exit_codepassed andcargo test -p coven-cli stream_claude_resumes_with_resume_flag_not_session_idpassed.Codex Task