Sicherheitsmodell
Grundannahme: Jedes Surface-JSON ist feindlich — das System rendert es, ohne sich kompromittieren zu lassen.
Die Verteidigungslinien
- Whitelist statt Blacklist: Nur registrierte Definitionen, nur im Schema deklarierte Props (Unbekanntes wird verworfen), nur Enum-Werte aus der Liste, nur registrierte Actions mit validierten Parametern, nur semantische Token-Pfade bei Token-Props.
- Escaping im Renderer: Jeder Kunden-String läuft durch
invisible_e(). Rich-Text ist die einzige HTML-Ausnahme — er wird serverseitig gegen eine Tag-/Attribut-Whitelist sanitisiert (kernel/sanitize.php);onclick,javascript:-URLs oder<script>überleben nicht. - URL-Schemata: Links und Bilder akzeptieren nur https/http/mailto bzw. relative Pfade — alles andere wird neutralisiert.
- Limits gegen Ressourcen-Angriffe: Surface max. 256 kB, 500 Nodes, Verschachtelungstiefe 20 — geprüft VOR dem Parsen bzw. beim Walken.
- Kein Code aus Daten: Es gibt keinen Weg, über eine Instanz CSS-Klassen, Styles oder JS einzuschleusen. Gestaltungsspielraum ist ausschließlich: Props (enum-begrenzt) + semantische Tokens (Registry-geprüft) + Slots (Regel-geprüft).
Warum Icons/SVG nie aus Instanzen kommen
Auch scheinbar harmlose Vektoren sind Angriffsfläche. Deshalb: ui.icon rendert nur aus der kuratierten Whitelist icons.json — Lucide-Icons werden beim Import sanitisiert, zur Laufzeit wird nie fremdes SVG geladen.
Vollständige Betrachtung inkl. bekannter Prototyp-Grenzen: SECURITY.md.