Sicherheitsrunde II: PTY-Label, Tool-Grenzen, atomare Schreibvorgänge
- term_start nur noch für das eigene term-<projekt>-Fenster — das (abgelöste) Panel-Fenster kann keine Shell mehr starten und beschreiben. Die Tauri-ACL greift für App-Commands nachweislich nicht (kein __app-acl__-Manifest, Prüfung gegen tauri 2.11.5); die Label-Prüfung ist damit die Schranke, nicht deren Verdopplung. - archive_panel verliert das dir-Argument: Archiv-Home samt dauerhafter Rechtevergabe (additionalDirectories + Edit-Allow) setzt nur noch die UI mit Nutzer-Dialog, kein Tool-Argument des Modells. - write_panel(path) liest nur noch aus Projekt-, Arbeits- und Archiv-Ordnern (canonicalize, symlink-fest), reguläre Dateien bis 2 MB mit hartem Byte-Cap — der promptfreie Weg umgeht das Read-Permission-Modell von Claude Code nicht mehr. - write_atomic (temp + rename) für alle JSON-Config-Schreiber: Projekt- Config, .claude/settings.json, Registry, App-Settings, pool.json, Pool-settings.json, claudes .claude.json, Todo-Hook. - write_secret_file: create_new mit 0600 statt schreiben-und-abdichten; kein umask-Fenster, Symlinks werden nicht gefolgt. - PTY-Umgebung: geerbte ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN entfernt. - panel_file & Geschwister prüfen die Projekt-ID (zweite Linie). - Befehlskacheln filtern Bidi-/Zero-Width-Zeichen aus Anzeige und Zwischenablage; der Lösch-Abgleich behält den Originaltext.
This commit is contained in:
@@ -50,10 +50,18 @@ impl Paths {
|
||||
}
|
||||
}
|
||||
|
||||
/// Zweite Linie: Die Projekt-ID wird zum Dateinamen der Panel-Kanäle — ein
|
||||
/// Wert mit Pfad-Bestandteilen (etwa aus einer verfälschten Registry oder
|
||||
/// AI_CONTROL_PROJECT-Env) bricht hier laut ab, statt einen Pfad zu bilden.
|
||||
fn checked(project: &str) -> &str {
|
||||
crate::domain::check_name(project).unwrap();
|
||||
project
|
||||
}
|
||||
|
||||
/// Panel-Datei eines Projekts (Kanal Skill -> Panel). Der Pfad landet als
|
||||
/// AI_CONTROL_PANEL in der PTY-Umgebung.
|
||||
pub(crate) fn panel_file(project: &str) -> PathBuf {
|
||||
Paths::real().panels_dir().join(format!("{project}.md"))
|
||||
Paths::real().panels_dir().join(format!("{}.md", checked(project)))
|
||||
}
|
||||
|
||||
/// Command-History eines Projekts (JSONL, anhängend — flüchtig, wird beim
|
||||
@@ -62,7 +70,7 @@ pub(crate) fn panel_file(project: &str) -> PathBuf {
|
||||
pub(crate) fn commands_file(project: &str) -> PathBuf {
|
||||
Paths::real()
|
||||
.panels_dir()
|
||||
.join(format!("{project}.commands.jsonl"))
|
||||
.join(format!("{}.commands.jsonl", checked(project)))
|
||||
}
|
||||
|
||||
/// Suchtreffer-Datei eines Projekts (JSON, letzter search_archive-Aufruf —
|
||||
@@ -71,7 +79,7 @@ pub(crate) fn commands_file(project: &str) -> PathBuf {
|
||||
pub(crate) fn search_file(project: &str) -> PathBuf {
|
||||
Paths::real()
|
||||
.panels_dir()
|
||||
.join(format!("{project}.search.json"))
|
||||
.join(format!("{}.search.json", checked(project)))
|
||||
}
|
||||
|
||||
/// Wiki-Puffer eines Projekts (JSON, jeweils letzte Wiki-Seite bzw. letztes
|
||||
@@ -80,7 +88,7 @@ pub(crate) fn search_file(project: &str) -> PathBuf {
|
||||
pub(crate) fn wiki_file(project: &str) -> PathBuf {
|
||||
Paths::real()
|
||||
.panels_dir()
|
||||
.join(format!("{project}.wiki.json"))
|
||||
.join(format!("{}.wiki.json", checked(project)))
|
||||
}
|
||||
|
||||
/// "~" bzw. "~/x" relativ zum Home auflösen; alles andere unverändert.
|
||||
|
||||
Reference in New Issue
Block a user