Skip to content

fix(commands): avoid untrusted coven path lookup#92

Open
BunsDev wants to merge 1 commit into
mainfrom
codex/fix-untrusted-path-lookup-in-/coven-command
Open

fix(commands): avoid untrusted coven path lookup#92
BunsDev wants to merge 1 commit into
mainfrom
codex/fix-untrusted-path-lookup-in-/coven-command

Conversation

@BunsDev

@BunsDev BunsDev commented Jun 15, 2026

Copy link
Copy Markdown
Member

Motivation

  • Prevent execution of attacker-controlled coven binaries discovered via untrusted PATH entries (repository-local or relative directories) when users run /coven subcommands.
  • Preserve the existing /coven UX while forcing resolution to a trusted absolute coven executable to eliminate PATH search-order hijacking risk.

Description

  • Add trusted resolver helpers: coven_executable_names, coven_binary_in_dir, coven_path_entry_is_trusted, coven_binary_from_path, and coven_binary_path to locate a concrete coven binary in absolute, non-project PATH entries.
  • Change coven_shell_out to call coven_binary_path() and spawn the resolved absolute path instead of Command::new("coven").
  • Ignore relative and current-directory PATH entries when resolving coven, and prefer a coven colocated with the running coven-code binary if present.
  • Add unit tests coven_binary_from_path_ignores_current_dir_and_relative_entries and coven_binary_from_path_rejects_untrusted_entries_without_fallback, plus a small test helper write_fake_coven and a minor import cleanup (use std::path::{Path, PathBuf};).

Testing

  • Ran the new unit tests with cargo test --package claurst-commands coven_binary_from_path -- --nocapture, and both tests passed.
  • Ran cargo check --package claurst-commands, which completed successfully for the package.
  • Attempted cargo check --workspace, which was blocked by a missing system dependency (alsa.pc) required by alsa-sys and therefore could not complete in this environment.
  • Workspace cargo clippy is blocked (and there are unrelated clippy findings in crates/tui/src/image_paste.rs) so full workspace linting was not completed here.

Codex Task

Copilot AI review requested due to automatic review settings June 15, 2026 13:22
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Jun 15, 2026 1:22pm

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Hardens /coven shell-outs by resolving coven to a trusted absolute executable path (instead of relying on PATH search order), reducing risk of PATH hijacking.

Changes:

  • Added helpers to resolve a trusted coven binary from a safe PATH entry (and prefer co-located binary).
  • Updated coven_shell_out to spawn the resolved absolute binary path.
  • Added unit tests and a small helper for creating fake coven binaries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +10180 to +10190
fn coven_path_entry_is_trusted(dir: &Path, cwd: Option<&Path>) -> bool {
if !dir.is_absolute() {
return false;
}
if let Some(cwd) = cwd {
if let (Ok(canonical_dir), Ok(canonical_cwd)) = (dir.canonicalize(), cwd.canonicalize()) {
return canonical_dir != canonical_cwd;
}
}
true
}
Comment on lines +10170 to +10178
fn coven_binary_in_dir(dir: &Path) -> Option<PathBuf> {
for name in coven_executable_names() {
let candidate = dir.join(name);
if candidate.is_file() {
return Some(candidate);
}
}
None
}
Comment on lines +11807 to +11826
#[test]
fn coven_binary_from_path_ignores_current_dir_and_relative_entries() {
let tmp = tempfile::tempdir().unwrap();
let project = tmp.path().join("project");
let relative = tmp.path().join("relative-bin");
let trusted = tmp.path().join("trusted-bin");
let trusted_coven = write_fake_coven(&trusted);
write_fake_coven(&project);
write_fake_coven(&relative);

let path = std::env::join_paths([
project.as_path(),
Path::new("relative-bin"),
trusted.as_path(),
])
.unwrap();

let resolved = coven_binary_from_path(Some(path.as_os_str()), Some(&project));
assert_eq!(resolved.as_deref(), Some(trusted_coven.as_path()));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants