Formatierter Text mit Werkzeugleiste und HTML-Ansicht (Schema v12)
Textblöcke dürfen ab v12 Auszeichnung tragen: fett, kursiv, unterstrichen, durchgestrichen, Code, hervorgehoben, hoch- und tiefgestellt, Absätze, Listen und Links. Die Entscheidung, was erlaubt ist, fällt auf dem Server beim Speichern - nicht im Editor und nicht beim Rendern. Was in der Datenbank landet, ist damit schon sicher, also kann kein Renderer das Filtern vergessen, und eine manipulierte Anfrage speichert nichts, was der Editor nicht anbietet. Nicht erlaubte Elemente werden ausgepackt, nicht gelöscht: der Text bleibt, nur die Auszeichnung geht. script, style, iframe und Verwandte verschwinden samt Inhalt, weil Auspacken ihren Code als Text sichtbar machen würde. Attribute fallen weg außer href an a, und auch das nur nach Adressprüfung. Ausgegeben wird formatierter Text nur ab v12, dann in einem div statt einem p, weil die Positivliste Absätze und Listen enthält. Ältere Dokumente behalten Klartextsemantik und werden weiter maskiert. Eine Inkonsistenz nebenbei behoben: ein Text mit einem < behielt echte Zeilenumbrüche, während alles andere <br> benutzte. Geprüft: 182 PHP-Tests / 685 Assertions unter PHP 8.2.12 und 8.4.22, darunter dreizehn Fälle durch den Filter mit acht Angriffen, dazu Editortest mit axe und öffentliche Browserprüfung. Die Werkzeugleiste selbst ist nicht bedient und nicht mit einem Screenreader geprüft. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d0938eec69
commit
790f42213c
16 files changed
+557
-30
No files matched your search
@@ -316,3 +316,19 @@ Geteilte Bereiche haben **keinen Entwurf und keine Veröffentlichung**. Sie ersc
|
||||
Damit ein Kopfbereich überhaupt frei baubar ist, gibt es einen Block `menu`: er zeigt einen Menüplatz, dessen Einträge weiterhin in der Menüverwaltung liegen. Die Marke ist ein gewöhnlicher Text- oder Bildblock. Im Template steht keine Navigation und keine Marke mehr.
|
||||
|
||||
**Ein echter Fehler kam dabei heraus, der nicht nur den eingesetzten Fußbereich betraf:** die Token-CSS war für die flache Struktur Sektion → Text geschrieben. `.block-column>.block-text:first-child` setzt eine Farbe für helle Hintergründe und gewinnt auf Spezifität gegen `.tone-ink .block-text`. Text in einer Spalte auf dunklem Grund war damit unlesbar – gemessen 1,87:1. Zwei gezielte Selektoren gleicher Spezifität, später in der Datei, stellen das richtig; helle Farbwelten bleiben unberührt.
|
||||
|
||||
## ADR 027 – Formatierter Text (Dokumentschema v12, 12.09.2026)
|
||||
|
||||
Textblöcke dürfen ab v12 Auszeichnung tragen: fett, kursiv, unterstrichen, durchgestrichen, Code, hervorgehoben, hoch- und tiefgestellt, Absätze, Listen und Links. Die Liste steht in `RichText::ALLOWED`.
|
||||
|
||||
**Die Entscheidung, was erlaubt ist, fällt auf dem Server beim Speichern** – nicht im Editor und nicht beim Rendern. Zwei Gründe: was in der Datenbank landet, ist damit schon sicher, also kann kein Renderer das Filtern vergessen; und eine manipulierte Anfrage kann nichts speichern, was der Editor nicht anbietet. Der Editor ist ein Vorschlag, der Server ist die Instanz.
|
||||
|
||||
Nicht erlaubte Elemente werden **ausgepackt, nicht gelöscht**: der Text bleibt, nur die Auszeichnung geht. Ein eingefügtes Word-Dokument verliert seine Gestaltung, nicht seinen Inhalt. Ausnahme sind `script`, `style`, `iframe`, `object`, `embed`, `template`, `noscript`, `svg` und `math` – sie werden samt Inhalt entfernt, weil Auspacken ihren Code als Text sichtbar machen würde. Attribute fallen restlos weg, außer `href` an `a`, und auch das nur nach derselben Adressprüfung wie überall; ein unbrauchbares Ziel macht aus dem Link Text. Externe Links bekommen `rel="noopener"`.
|
||||
|
||||
Ausgegeben wird formatierter Text **nur ab v12**, und dann unescaped in einem `div` statt einem `p` – die Positivliste enthält Absätze und Listen, die in einem `p` nicht stehen dürfen. Ältere Dokumente behalten Klartextsemantik und werden weiterhin maskiert; der bestehende XSS-Test für v1 gilt unverändert. Ein Dokument wechselt erst auf v12, wenn jemand einen Textblock formatiert bearbeitet.
|
||||
|
||||
Zeilenumbrüche werden in beiden Zweigen zu `<br>`. Vorher behielt ein Text, der zufällig ein `<` enthielt, echte Zeilenumbrüche, während alles andere `<br>` benutzte – zwei Darstellungen desselben Umbruchs, die beim nächsten CSS-Wechsel auseinandergelaufen wären. Innerhalb von `code` bleiben Umbrüche unangetastet.
|
||||
|
||||
Ein Textblock, der nach dem Filtern leer ist, wird abgewiesen – dieselbe Regel wie für einen von Hand geleerten Textblock. Wer nur ein verbotenes Element einfügt, bekommt also eine Meldung statt eines stillschweigend leeren Blocks.
|
||||
|
||||
Im Editor gibt es zwei Sichten auf denselben Wert: eine Formatierungsansicht mit Werkzeugleiste und eine HTML-Ansicht mit der Auszeichnung. Eingefügter Inhalt wird als reiner Text übernommen. Die Werkzeugleiste nutzt `execCommand`; das ist abgekündigt, aber das Einzige, was alle Browser für diese Aufgabe umsetzen, und da der Server ohnehin normalisiert, kann eine Browsereigenheit nichts Unerwartetes speichern.
|
||||
Reference in new issue
Block a user