Vier Befunde aus einer Prüfung entlang der Angriffsflächen (MCP-Tools,
Command-Grenze, Credentials, Schreibpfade und Abhängigkeiten):
- todo.rs: Der SessionStart-Hook interpolierte den Projektpfad unquotiert in
eine Shell-Kommandozeile, die Claude Code bei jedem Sessionstart ausfuehrt.
Ein Ordner `repo$(...)` -- etwa aus einem geklonten Fremd-Repo -- ergab
dauerhafte Codeausfuehrung; ein Leerzeichen zerbrach den Hook still.
Der Pfad wird jetzt gequotet, inklusive Apostroph.
- project_pool_dir: Der Pool-Name kommt aus der ai-control.json im
Projektordner, also aus einer versionierten Datei. Ungeprueft bestimmte er
mit ../ ein beliebiges Verzeichnis als CLAUDE_CONFIG_DIR, dessen
settings.json wiederum apiKeyHelper traegt -- ein Kommando, das beim
Sessionstart laeuft. Jetzt durch check_name abgesichert.
- check_name: Steuerzeichen, Backslash und fuehrender Punkt werden abgelehnt.
Ein Newline im Projektnamen hing bisher eigene Schluessel an die .desktop-
Datei; Exec= braucht keinen Schraegstrich, den der alte Check verbot.
- markdown.ts: Bilder duerfen nur noch lokale Ziele laden. Ein auswaertiges
<img> laedt ohne Zutun und meldet damit IP, Zeitpunkt und im Pfad kodierte
Daten -- der Panelinhalt stammt aus einer LLM-Session, ist also
injizierbar. Schema-relative URLs (//host/x) waren durch ein zu laxes
Muster erfasst. Links bleiben auswaerts erlaubt, jetzt mit
rel="noopener noreferrer". escapeHtml escaped zusaetzlich das Apostroph.
Dazu cargo audit nachgeholt: plist 1.9.0 -> 1.10.0 hebt quick-xml auf 0.41.0
und schliesst RUSTSEC-2026-0194/0195 fuer den Laufzeitpfad. Die zweite
Instanz von quick-xml 0.39.4 bleibt ueber wayland-scanner im Lockfile --
ein proc-macro, das nur zur Compile-Zeit laeuft und ausgelieferte
Protokoll-XMLs parst, nicht im Binary landet.
77 Rust-Tests, 39 Frontend-Tests.
- archive_search: match_expr in search() aufgelöst. sanitize_query lief zweimal
pro Anfrage, und die Leer-Entscheidung stand an zwei Stellen mit leicht
abweichender Bedingung.
- Der Tag-Filter geht jetzt durch dieselbe Quoting-Regel wie der Volltext. Ein
leerer Tag ergab tags:"" und damit einen Syntaxfehler — erreichbar durch das
angetippte #, den ersten Tastendruck jeder Tag-Suche.
- sanitize_query von 26 auf 12 Zeilen: split('"') und split_whitespace statt
handgeschriebenem Tokenizer. Gleiches Ergebnis fuer alle Testeingaben.
- TerminalConfig bekommt ebenfalls serde flatten. Der Block wird als Ganzes
mitgeschrieben, ein terminal.fontSize waere also weiterhin verloren gegangen;
set_terminal_config_in traegt die unbekannten Keys jetzt herueber.
- markdown.test.ts enthielt ein literales NUL-Byte, wodurch git die Datei als
binaer behandelte. Der Test erzeugt das Zeichen jetzt selbst.
- Kleineres: commands_delete-Bedingung als direkter Vergleich, eine
Verschachtelungsebene in pool.rs, zwei redundante Kommentarbloecke.
commands_delete benennt sich in der Doku als Provisorium.
- ProjectConfig reicht unbekannte Keys durch (serde flatten). Bisher verlor
jeder read-modify-write die Felder neuerer Versionen; so ging archiveHome
bei der Pool-Zuweisung durch einen älteren Build verloren.
- Archiv-Suche: Nutzereingabe wird in einen FTS5-Ausdruck übersetzt, der nicht
scheitern kann. ai-control, C++ oder eine halbe Phrase warfen bisher einen
Syntaxfehler — bei der Live-Suche in jedem Tippzwischenstand.
- commands_delete: Befehlstext als Identität, Indizes werden geprüft. Bisher
Panik oder Löschen der falschen Kachel, wenn die Panel-Indizes der Datei
hinterherhingen.
- Archivieren überschreibt keine Datei mehr: Der Stempel hat Minutenauflösung,
bei Kollision wird -2, -3, ... angehängt.
- archive_panel prüft erst auf leeres Panel, dann wird das Archiv-Home gesetzt;
bisher blieb ein umkonfiguriertes Home trotz Meldung "nicht archiviert".
- Kaputte .claude.json eines Pools wird nicht mehr durch eine frische ersetzt;
nur eine fehlende Datei rechtfertigt das.
- Archiv-Formular leert beim Schließen — sonst galten Ordner und Schlagwörter
des vorigen Dokuments unbemerkt fürs nächste.
- Markdown fürs Panel entschärft (src/markdown.ts): rohes HTML wird als Text
ausgegeben, Link- und Bildziele auf harmlose Schemata beschränkt. Das Panel
teilt sich den Webview mit dem Terminal, dessen term_write in die PTY
schreibt; ohne CSP war das ein Weg von Fremdinhalt zu Befehlsausführung.
Regressionstests je Fix: 73 Rust-Tests, 35 Frontend-Tests.