Eigenes CSS je Element für alle, eigenes Skript nur für Administratoren
Dokumentschema v13. Der neue Reiter "Erweitert" im Editor nimmt zu jedem
Element eigenes CSS und eigenes Skript auf.
Eigenes CSS parst `CustomCode` und schreibt es selbst wieder aus, mit einem
Selektor, den die Klasse setzt und der nie aus der Eingabe stammt. Erlaubt
sind Eigenschaften für das Element und verschachtelte Regeln mit `&`
(`&:hover`, `& > p`, `& .block-text`). Weil neu serialisiert wird, kann eine
überzählige `}` den Block nicht verlassen. Abgewiesen: @-Regeln,
Backslash-Escapes, `expression()`, fremde Selektoren und jede Adresse außer
einem einzelnen `/` oder `https://`. Das darf jeder mit Editorrolle.
Eigenes Skript ist etwas anderes: beliebiges JavaScript auf der
veröffentlichten Website. Deshalb nur für Administratoren, durchgesetzt beim
Schreiben über einen Vergleich mit dem gespeicherten Stand - ein Editor kann
eine Seite mit Skript weiter bearbeiten, das Skript aber nicht anfassen, auch
nicht über eine selbst gebaute Anfrage. Ausgeliefert wird es als
`/assets/seite/{id}.js` und nur für veröffentlichte Seiten, jedes Skript in
einer eigenen Closure mit gesuchtem `element` und `try`/`catch`. Nur eine
Seite mit eigenem Skript sendet `script-src 'self'`, jede andere behält
`script-src 'none'`; inline ist nirgends erlaubt. In der Editorvorschau wird
nichts ausgeführt.
Zwei echte Löcher kamen beim Testen heraus und sind behoben: `& .block-text`
wurde zu `#id.block-text`, weil das führende Leerzeichen wegtrimmt wurde, und
`url(//fremd.example/x.png)` kam durch, weil jede Adresse mit `/` erlaubt war.
201 PHP-Tests / 716 Assertions unter PHP 8.2.12 und 8.4.22, Playwright-
Editortest und öffentliche Browserprüfung grün. Nicht geprüft: der Reiter
"Erweitert" ist nicht von Hand bedient und nicht mit einem Screenreader
getestet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
790f42213c
commit
a22a7f7fd7
15 files changed
+544
-14
No files matched your search
@@ -332,3 +332,18 @@ Zeilenumbrüche werden in beiden Zweigen zu `<br>`. Vorher behielt ein Text, der
|
||||
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.
|
||||
|
||||
## ADR 028 – Eigenes CSS und eigenes Skript je Element (Dokumentschema v13, 12.09.2026)
|
||||
|
||||
Umut wollte an jedem Element eigenes CSS **und** eigenes Skript setzen können. Beides ist umgesetzt, aber nicht gleich behandelt, weil beides sehr Unterschiedliches anrichten kann.
|
||||
|
||||
**Eigenes CSS** wird von `CustomCode` geparst und selbst wieder ausgeschrieben, mit einem Selektor, den diese Klasse setzt und der nie aus der Eingabe stammt. Akzeptiert werden Eigenschaften für das Element und verschachtelte Regeln, die mit `&` beginnen – `&:hover`, `& > p`, `& .block-text`. Weil die Ausgabe neu serialisiert wird, kann eine überzählige `}` den Block nicht verlassen. Abgewiesen werden @-Regeln, Backslash-Escapes, `expression()` und jede Adresse, die nicht mit einem einzelnen `/` oder `https://` beginnt. Fremde Selektoren gibt es nicht. Das darf jeder mit Editorrolle: das Ergebnis kann hässlich sein, aber keinen Code ausführen.
|
||||
|
||||
**Eigenes Skript ist etwas anderes.** Es ist beliebiges JavaScript auf der veröffentlichten Website; wer es setzen darf, kann Code im Browser jedes Besuchers und jedes Administrators ausführen. Das lässt sich nicht entschärfen, nur eingrenzen:
|
||||
|
||||
- **Nur Administratoren.** Durchgesetzt wird das beim Schreiben, indem die Skripte der eingehenden Fassung mit den gespeicherten verglichen werden. Ein Editor kann eine Seite mit Skript also weiter bearbeiten und speichern, aber das Skript nicht anfassen – auch nicht über eine selbst gebaute Anfrage. Im Panel ist das Feld für ihn nur lesbar, was dieselbe Regel bloß sichtbar macht.
|
||||
- **Als eigene Datei, nicht inline.** `/assets/seite/{id}.js` liefert die Skripte einer **veröffentlichten** Seite, jedes in einer eigenen Closure mit bereits gesuchtem `element` und einem `try`/`catch`, damit ein Fehler die anderen nicht mitnimmt. Ein Skript aus einem Entwurf wird nicht ausgeliefert.
|
||||
- **Die strenge Richtlinie bleibt die Voreinstellung.** Nur eine Seite, die tatsächlich ein eigenes Skript trägt, sendet `script-src 'self'`. Jede andere behält `script-src 'none'`. Inline-Skript ist nirgends erlaubt.
|
||||
- **In der Editorvorschau wird nichts ausgeführt.** Die Vorschau soll das Layout zeigen, nicht Code laufen lassen, der die Seite unter den Händen des Bearbeiters verändert.
|
||||
|
||||
Zwei echte Löcher kamen beim Testen heraus. `& .block-text` wurde zu `#id.block-text`, weil das führende Leerzeichen wegtrimmt wurde – aus dem Nachfahren wurde derselbe Knoten, die Regel traf das falsche Element. Und `url(//fremd.example/x.png)` kam durch, weil die Prüfung jedes `/` erlaubte: eine protokollrelative Adresse hätte über das Schema der Seite von Dritten geladen. Beides ist behoben und durch Tests abgedeckt.
|
||||
Reference in new issue
Block a user