Commit Graph
3 Commits
Author SHA1 Message Date
Nick Szaunig abdebfc477 fix: Admin-Upload scheiterte an der CSRF-Pruefung (403 "Ungueltige Anfrage.")
Die Same-Origin-Pruefung verglich den Origin-Header gegen
new URL(request.url).host. Next.js rekonstruiert request.url aber aus der
internen Bind-Adresse des Servers, NICHT aus dem Host-Header, den der
Browser tatsaechlich adressiert hat — reproduzierbar liefert request.url
"localhost:3999", waehrend der Browser "127.0.0.1:3999" aufgerufen hat.

Damit schlug jeder Admin-Upload mit 403 fehl, sobald die Seite unter einem
anderen Namen als dieser internen Adresse erreicht wurde: oeffentliche
Domain hinter dem Reverse-Proxy, LAN-IP, oder schlicht 127.0.0.1 statt
localhost. Der 2025 nachgeruestete Fallback auf NEXT_PUBLIC_SITE_URL half
nur, wenn diese Variable gesetzt ist und exakt passt — in .env fehlt sie.

Der Origin wird jetzt gegen alle plausiblen eigenen Hosts geprueft, in
dieser Reihenfolge: X-Forwarded-Host (vom eigenen Proxy gesetzt, Caddy
verwirft einen vom Client mitgeschickten Wert), Host (was der Browser
adressiert hat — derselbe Vergleich, den Next.js fuer Server Actions
intern anstellt), request.url und zuletzt NEXT_PUBLIC_SITE_URL.

Der CSRF-Schutz bleibt dabei vollstaendig: eine fremde Seite kann bei
einem Cross-Site-Request weder Host noch X-Forwarded-Host bestimmen — den
Host setzt der Browser aus der Ziel-URL, eigene Header liessen sich nur
per fetch() setzen, was einen CORS-Preflight ausloest, den dieser
Endpunkt nicht beantwortet. Ein gefaelschter POST traegt also weiterhin
zwangslaeufig einen fremden Origin und wird abgewiesen (durch Test und
manuelle Gegenprobe belegt).
2026-09-13 23:15:28 +02:00
Nick SzaunigandClaude Sonnet 5 d03cada256 fix: CSRF-Origin-Pruefung faelschlich abgelehnt hinter selbst betriebenem Reverse-Proxy
isTrustedOrigin() verglich den Origin-Header ausschliesslich gegen den von
Next.js aus request.url rekonstruierten Host. Hinter dem eigenen
Caddy/nginx-Reverse-Proxy (docker-compose.yml, k8s/) ist dieser Wert nicht
in jeder Konstellation zuverlaessig derselbe wie der echte, oeffentliche
Host im Origin-Header - das fuehrte live zu "Ungueltige Anfrage." bei
jedem Admin-Upload, obwohl der Request vom eigenen Frontend kam. Prueft
jetzt zusaetzlich gegen getBaseUrl() (NEXT_PUBLIC_SITE_URL), genau wie
lib/url.ts es fuer denselben Zweck bereits vormacht - als reine
ODER-Erweiterung, damit ein falsch gesetztes NEXT_PUBLIC_SITE_URL nicht
umgekehrt bislang funktionierende Endpunkte wie /api/checkout blockiert.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-11 16:06:56 +02:00
Nick SzaunigandClaude Sonnet 5 154b75e0d8 test: Testabdeckung fuer CSRF-Schutz, Entra-ID-SSO und DHL-Client
Keine der in dieser Session neu hinzugefuegten sicherheitskritischen
Module (lib/csrf.ts, lib/entra.ts, lib/dhl.ts) hatte bisher Tests.

- csrf.test.ts: Same-Origin-Erkennung, Ablehnung gefaelschter
  Cross-Origin-Requests, tolerantes Verhalten bei fehlendem/kaputtem
  Origin-Header.
- entra.test.ts: PKCE-Paar-Erzeugung (RFC 7636), Authorize-URL-Aufbau,
  Extraktion des verifizierten E-Mail-Claims (nie ein unplausibles
  Feld raten).
- dhl.test.ts: Adress-Mapping (Strasse/Hausnummer-Trennung,
  ISO2->ISO3-Laendercode), Fehlerbehandlung bei nicht unterstuetztem
  Land, DHL-Validierungsfehlern und HTTP-Fehlern, statt einen falschen
  Erfolg vorzutaeuschen.

Alle 118 Tests (13 Dateien) gruen, tsc --noEmit clean.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-04 08:48:08 +02:00