feat: enhance safety and crash resilience in file operations; add fsync to critical writes and checks for path traversal
This commit is contained in:
+14
-6
@@ -18,23 +18,31 @@ pub struct Harness;
|
||||
impl Harness {
|
||||
/// Decide whether a tool call is allowed to execute.
|
||||
///
|
||||
/// Flow: if the tool isn't flagged risky, allow immediately → otherwise
|
||||
/// defer to `classify`.
|
||||
/// Flow: if the tool isn't flagged risky, allow immediately → basic
|
||||
/// content checks (path traversal) → defer to `classify`.
|
||||
///
|
||||
/// Why: `_args` and `_workspace_roots` are accepted for a future
|
||||
/// content-aware classifier but currently unused — `classify` is a
|
||||
/// stub that always allows.
|
||||
/// Why: `classify` is currently a stub that always allows; the basic
|
||||
/// checks here serve as defense-in-depth alongside the shell filters
|
||||
/// and `resolve_path` in the tool modules.
|
||||
///
|
||||
/// Return: `Verdict::Allow` or `Verdict::Block(reason)`.
|
||||
pub fn gate_tool_call(
|
||||
tool_name: &str,
|
||||
_args: &serde_json::Value,
|
||||
args: &serde_json::Value,
|
||||
_workspace_roots: &[&std::path::Path],
|
||||
) -> Verdict {
|
||||
|
||||
if !crate::tool::tool_is_risky(tool_name) {
|
||||
return Verdict::Allow;
|
||||
}
|
||||
// Basic path traversal check for file-mutating tools.
|
||||
if matches!(tool_name, "write" | "edit" | "delete") {
|
||||
if let Some(path) = args.get("path").and_then(|v| v.as_str()) {
|
||||
if path.contains("..") {
|
||||
return Verdict::Block("path traversal detected in 'path' argument".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
Self::classify(tool_name)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user