Root cause
Path & link handling
The guard walks to an existing ancestor and appends the missing path tail before checking the sandbox boundary.
How AI contributed: Flawed AI-written codePublished Jul 18, 2026 in
nearai/ironclawAll 2 findings in this repository
Provisional finding. Full causal and release verification remains incomplete.
Root cause
The guard walks to an existing ancestor and appends the missing path tail before checking the sandbox boundary.
Fix
The repaired path guard checks for a dangling symbolic link and returns an authorization error.
Case facts
@@ -100,6 +114,13 @@+ // Walk up to the nearest existing ancestor directory, canonicalize it,+ // then re-append the remaining tail. This handles the case where a+ // symlink sits above the new file.+ let mut ancestor = resolved.as_path();+ let mut tail_parts: Vec<&std::ffi::OsStr> = Vec::new();+ loop {+ if ancestor.exists() {+ let canonical_ancestor = ancestor .canonicalize()- .unwrap_or_else(|_| parent.to_path_buf());- if let Some(filename) = resolved.file_name() {- canonical_parent.join(filename)- } else {- resolved.clone()+ .unwrap_or_else(|_| ancestor.to_path_buf());+ let mut result = canonical_ancestor;+ for part in tail_parts.into_iter().rev() {+ result = result.join(part);@@ -95,9 +95,17 @@ // For existing paths, canonicalize to resolve symlinks. // For non-existent paths, the lexical normalization above already removed // all `..` components, so starts_with is reliable. let check_path = if resolved.exists() { resolved.canonicalize().unwrap_or_else(|_| resolved.clone())+ } else if std::fs::symlink_metadata(&resolved)+ .map(|m| m.file_type().is_symlink())+ .unwrap_or(false)+ {+ return Err(ToolError::NotAuthorized(format!(+ "Path is a dangling symlink: {}",+ path_str+ ))); } else { // Walk up to the nearest existing ancestor directory, canonicalize it, // then re-append the remaining tail. This handles the case where a // symlink sits above the new file.AI-assisted change 5287928e4e4667506f52bec161feb9106589aa55dce6bf865984e1fae37f5a80 · Fix 02854321104f46baa14f18c330c7512a63a9015547a8e1e7b6c84342003855c0