Inhaltsrichtlinie (CSP): mit Pruefsummen statt mit unsafe-inline

Fuenf Schutz-Kopfzeilen waren gesetzt, die wichtigste fehlte. Sie
entscheidet als einzige darueber, ob eingeschleuster Text zu
ausgefuehrtem Code wird oder sichtbarer Text bleibt.

WARUM NICHT DER BEQUEME WEG

Ueblich waere script-src 'self' 'unsafe-inline'. Eine Zeile, nichts geht
kaputt -- und der Schutz ist weg: Der Browser kann nicht unterscheiden,
ob ein Skript im Seitentext vom Entwickler stammt oder von einem
Angreifer. Das Ergebnis ist eine Kopfzeile, die gut aussieht und im
Ernstfall nichts tut.

Der Bestand liess den sauberen Weg zu: keine fremden Skriptquellen,
keine externen Schriften, ein Inline-Block je Seite. Von jedem Block
wird die Pruefsumme gebildet.

DIE PRUEFSUMMEN STEHEN BEWUSST NICHT IM CODE

Das waere hier eine Falle mit Ansage: Statische Dateien gehen per "git
pull" live, OHNE Neustart. Eine fest hinterlegte Summe waere nach der
naechsten Textaenderung falsch -- und die Seite wuerde ihr eigenes
Skript nicht mehr ausfuehren. Sichtbar erst im Browser des Besuchers,
nicht beim Deploy, und aussehend wie kaputtes JavaScript.

Deshalb liest die Middleware die Datei selbst und merkt sich das
Ergebnis, solange die Aenderungszeit gleich bleibt. Ein Test aendert
index.html im laufenden Betrieb und prueft, dass die Summe nachzieht
und die Seite weiterlaeuft.

WAS DER TEST GEFUNDEN HAT

Die erste Fassung haette die Startseite und stimmen.html beschaedigt:
Team-Fotos, Event des Jahres und die Stimmen kommen von der
postfach-Subdomain, img-src erlaubte nur 'self'. Der Deploy haette
Erfolg gemeldet, der Server waere gestartet -- und die Bilder waeren
weg gewesen. Gefunden, weil der Test alle 48 Seiten in einem echten
Browser oeffnet und mitschreibt, was blockiert wird.

Ein zweiter Fehlschlag lag am Test selbst: Er verlangte eine Pruefsumme
auf jeder Seite, auch auf denen ohne Inline-Block. Ein Test, der
Unmoegliches fordert, wird frueher oder spaeter abgeschaltet -- er
unterscheidet jetzt nach dem tatsaechlichen Inhalt der Datei.

DREI onclick-ATTRIBUTE ENTFERNT

Sie haetten 'unsafe-inline' erzwungen. Zweimal ein "Coming soon"-Knopf,
dessen onclick nur Klicks abfing -- ein <a> ohne href tut das von
selbst, ganz ohne Skript. Einmal ein Schliessen-Knopf im
Verwaltungsbereich, jetzt mit angehaengtem Zuhoerer.

GEGENPROBE

Ohne sie waere der Rest wertlos: Eine Richtlinie, die alles erlaubt,
blockiert auch nichts und besteht jede Pruefung. Der Test schleust
deshalb echten Code ein -- ein Inline-Skript und eines von fremder
Adresse -- und beide muessen scheitern.

style-src behaelt 'unsafe-inline': 587 style-Attribute im Bestand, deren
Umbau ein echtes Risiko fuers Aussehen waere, bei kleinem Gewinn. Ueber
Stile laesst sich verschleiern und ueberdecken, aber kein Code
ausfuehren. Bleibt als eigener Punkt auf der Liste.

15 Pruefungen gruen, 48 Seiten sauber, Portfolio-Suite unveraendert 35.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-26 14:05:42 +02:00
co-authored by Claude Opus 5
parent 094a69732b
commit 03a533f143
7 changed files with 392 additions and 4 deletions
+1 -1
View File
@@ -58,7 +58,7 @@
<p data-i18n="vv_wer_tiktok">Auf TikTok findet ihr mich unter:</p>
<a class="btn-tiktok" href="https://www.tiktok.com/@o.o.vanessa.o.o" target="_blank" rel="noopener" style="margin-bottom:.7rem;"><span class="btn-tiktok-note" aria-hidden="true">♪</span><span class="btn-tiktok-text">TikTok</span></a>
<br />
<a class="btn-silver" href="#" aria-disabled="true" onclick="return false;" style="margin-bottom:1rem;"><span class="btn-silver-spark" aria-hidden="true">✨</span><span class="btn-silver-text" data-i18n="vv_coming_soon">Coming soon…</span><span class="btn-silver-spark" aria-hidden="true">✨</span></a>
<a class="btn-silver" aria-disabled="true" style="margin-bottom:1rem;"><span class="btn-silver-spark" aria-hidden="true">✨</span><span class="btn-silver-text" data-i18n="vv_coming_soon">Coming soon…</span><span class="btn-silver-spark" aria-hidden="true">✨</span></a>
<p data-i18n="vv_wer_1" style="margin-top:1.4rem;">Ich bin ein Mensch, der mit dem Herzen denkt, unglaublich loyal ist und für die Menschen kämpft, die ihm wichtig sind.</p>
<p data-i18n="vv_wer_2">Wenn ich zu jemandem Vertrauen aufgebaut habe, gibt es für mich kein „halb“. Dann bin ich da – unabhängig davon, ob gerade gute oder schwierige Zeiten herrschen.</p>
<p data-i18n="vv_wer_3">Freundschaft, Zusammenhalt und Ehrlichkeit bedeuten mir mehr als alles andere. Für mich zählen keine Fassaden, sondern der Charakter eines Menschen. Wenn ich jemanden unterstütze, dann nicht, weil es von mir erwartet wird, sondern weil ich aus voller Überzeugung hinter diesem Menschen stehe.</p>