Irrefuehrende Sicherheitszusagen entfernen, OWASP-Durchgang festhalten
Zwei Kommentare versprachen Schutz, den es nicht gab. Das ist schlimmer als eine fehlende Zusage, weil man sich darauf verlaesst: - In middleware.ts stand "Ohne Authentifizierungs-Cookie gar nicht erst weiterreichen". Die Middleware prueft keine Anmeldung, sie setzt Kopfzeilen; die Liste steuert allein den Cache-Control-Kopf. Wer den Satz glaubt, verzichtet an einer neuen Seite auf erfordereBenutzer(). Die Liste heisst jetzt OHNE_CACHE_SPERRE und sagt selbst, was sie ist. - In datei.ts hiess es, die Pfadpruefung fange "Symlink-Tricks" ab. resolve() rechnet mit Zeichenketten und folgt keinem Link - dafuer braeuchte es realpath(). Nachgeruestet wird es nicht: Wer dort einen Symlink anlegen kann, hat schon Schreibrechte im Datenverzeichnis. Der Satz musste trotzdem weg. Dazu docs/SICHERHEIT.md: Bedrohungsmodell, der Durchgang entlang der OWASP Top 10 - und ein eigener Abschnitt darueber, was ausdruecklich NICHT geschuetzt ist. Aus dem OWASP-Durchgang kamen keine weiteren Funde. Zwei Stellen sahen danach aus und waren es nicht: Prisma.join() in suche.ts fuegt nur bereits parametrisierte Fragmente zusammen, und der Suchausschnitt mit den <mark>-Markern aus ts_headline wird zerlegt und als React-Kinder gerendert, nicht als HTML - obwohl die Quelle der OCR-Text hochgeladener Dokumente ist. Refs #38
This commit is contained in:
@@ -34,8 +34,18 @@ function wurzel(): string {
|
||||
/**
|
||||
* Baut den Dateipfad - und prueft danach noch einmal, dass er wirklich
|
||||
* unterhalb des Ablageverzeichnisses liegt. Der Schluessel ist zwar bereits
|
||||
* streng geprueft, aber diese zweite Sperre kostet nichts und faengt auch
|
||||
* Symlink-Tricks und Windows-Eigenheiten ab.
|
||||
* streng geprueft, aber diese zweite Sperre kostet nichts.
|
||||
*
|
||||
* Was sie NICHT abfaengt, obwohl hier lange das Gegenteil stand: Symlinks.
|
||||
* resolve() rechnet nur mit Zeichenketten und folgt keinem Link - dafuer
|
||||
* braeuchte es realpath(). Ein untergeschobener Symlink im Ablageverzeichnis
|
||||
* wuerde also nicht auffallen.
|
||||
*
|
||||
* Nachgeruestet wird das trotzdem nicht, und zwar aus einem Grund und nicht
|
||||
* aus Bequemlichkeit: Wer dort einen Symlink anlegen kann, hat bereits
|
||||
* Schreibrechte im Datenverzeichnis des Servers - dann ist der Umweg ueber
|
||||
* einen Link die Sorge, die am wenigsten draengt. Der Satz musste
|
||||
* verschwinden, weil er eine Sicherheit versprach, die es nie gab.
|
||||
*/
|
||||
function pfadFuer(schluessel: string): string {
|
||||
const geprueft = schluesselErfordern(schluessel)
|
||||
|
||||
+16
-3
@@ -30,8 +30,21 @@ import { NextResponse, type NextRequest } from 'next/server'
|
||||
* Data-URI eingebettet, statt sie ueber einen Fremddienst zu holen.
|
||||
*/
|
||||
|
||||
/** Ohne Authentifizierungs-Cookie gar nicht erst weiterreichen. */
|
||||
const OEFFENTLICHE_PFADE = [
|
||||
/**
|
||||
* Seiten, die auch ohne Anmeldung sinnvoll im Verlauf stehen duerfen.
|
||||
*
|
||||
* ACHTUNG - was diese Liste NICHT ist: eine Zugriffskontrolle. Frueher
|
||||
* stand hier "Ohne Authentifizierungs-Cookie gar nicht erst weiterreichen",
|
||||
* und das war schlicht falsch: Die Middleware prueft keine Anmeldung, sie
|
||||
* setzt Kopfzeilen. Ausgewertet wird die Liste einzig fuer die Frage, ob
|
||||
* "Cache-Control: no-store" gesetzt wird.
|
||||
*
|
||||
* Der Irrtum waere teuer geworden: Wer den Satz glaubt, verzichtet an einer
|
||||
* neuen Seite auf erfordereBenutzer() - "die Middleware faengt das ja ab".
|
||||
* Sie faengt nichts ab. Der Zugriffsschutz sitzt in
|
||||
* src/lib/auth/sitzung.ts, und nur dort.
|
||||
*/
|
||||
const OHNE_CACHE_SPERRE = [
|
||||
'/anmelden',
|
||||
'/ersteinrichtung',
|
||||
'/datenschutz',
|
||||
@@ -79,7 +92,7 @@ export function middleware(anfrage: NextRequest) {
|
||||
|
||||
// Verhindert, dass ein Bericht oder Beleg im Verlauf des Browsers
|
||||
// zwischengespeichert wird.
|
||||
if (!OEFFENTLICHE_PFADE.some((pfad) => anfrage.nextUrl.pathname.startsWith(pfad))) {
|
||||
if (!OHNE_CACHE_SPERRE.some((pfad) => anfrage.nextUrl.pathname.startsWith(pfad))) {
|
||||
antwort.headers.set('Cache-Control', 'no-store, must-revalidate')
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user