fix: confine MCP agents' files to allowed folders; recovery discard deletes only recovery entries (#205) (#578)

Agent tool calls (MCP, and bridged control requests carrying allow_paths) reach files only in the open design's folder (strictly inside home or the temporary folder, not in a hidden folder, and never its hidden files), the app's recovery folder, the server's private scratch folder and each --allow-path; --allow-any-path lifts the limit. Paths are resolved first, so .. and symlinks that lead out (including a save through a link, #845) are refused. On Windows, UNC, device, NT, verbatim non-drive, drive-relative, alternate-stream, reserved-device and 8.3 short-name paths are refused before any file system call, and the resolved path must be on a local drive. doc.recovery_discard and doc.recover {discard} delete only real recovery entries. Docs: mcp.md, control-protocol.md, README.
This commit is contained in:
Kevin Ravensberg authored and GitHub committed 2026-10-13 18:24:08 -04:00
1 parent 3d3f9b626f
commit 96f6424aec
23 files changed
+1000 -37

No files matched your search

+4
View File
@@ -117,6 +117,10 @@ fn text_source(p: &Value, cmd: &str, old: Option<(String, Vec2, f64, f64, Option
Some(Value::String(f)) => Some(f.trim().to_string()),
Some(_) => return Err(bad(cmd, "`font` must be a font family name or a font file path")),
};
// A font file an agent names must lie in its folders (installed families are found by name).
if let Some(path) = font.as_deref().and_then(solidcraft_sketch::font_file_path) {
solidcraft_io::vfs::check(&path.to_string_lossy()).map_err(|e| bad(cmd, e.to_string()))?;
}
// An unknown font or an unreadable file is an error now, not a lost link later.
solidcraft_sketch::font_data(font.as_deref()).map_err(|e| bad(cmd, e.to_string()))?;
Ok(LinkSource::Text { text, at, height, angle, font })