-- Sitzungen serverseitig entwertbar machen --------------------------------- -- Bis hierher war das Sitzungs-Cookie nur HMAC-signiert: Wer es einmal hatte, -- kam damit unbegrenzt hinein — auch nachdem das Passwort zurückgesetzt oder -- die Rolle entzogen wurde. Genau der Vorgang, der ein übernommenes Konto -- retten soll, half also nicht. -- -- `session_epoch` wird bei jedem Passwortwechsel und jeder Rollenänderung -- hochgezählt. Das Cookie trägt den Stand mit; stimmt er nicht mehr, gilt es -- nicht mehr. Ein Zähler statt eines Zeitstempels, weil er keine Uhrzeit- -- Ungenauigkeiten kennt. ALTER TABLE users ADD COLUMN IF NOT EXISTS session_epoch integer NOT NULL DEFAULT 0; -- Für die Namensvergabe: `renames.ts` fragt bei jedem fertigen Bild, ob ein -- Name schon vergeben ist — ohne Index war das ein voller Tabellendurchlauf. CREATE INDEX IF NOT EXISTS items_filename_idx ON items(filename); -- Aufräumen: Beide Tabellen wuchsen unbegrenzt. CREATE INDEX IF NOT EXISTS share_views_at_idx ON share_views(at); CREATE INDEX IF NOT EXISTS password_resets_expires_idx ON password_resets(expires_at); -- Zähler für verschiedene Besucher je Teilen-Link. Vorher wurde er bei jedem -- Aufruf der Verwaltungsseite über `count(DISTINCT ip_hash)` aus share_views -- gerechnet — das wurde mit wachsender Tabelle zäh und machte die Seite -- angreifbar, weil jeder mit dem Link beliebig viele Zeilen erzeugen konnte. ALTER TABLE shares ADD COLUMN IF NOT EXISTS besucher integer NOT NULL DEFAULT 0; -- Nur eine Zeile je Link, Besucher und Stunde: Ohne diese Grenze konnte ein -- Empfänger (oder ein -Tag auf irgendeiner Seite) die Tabelle unbegrenzt -- füllen und damit die Platte volllaufen lassen. -- -- Der Stundenwert wird beim Schreiben mitgegeben statt im Index gerechnet: -- `date_trunc` auf einem timestamptz hängt an der Zeitzonen-Einstellung und ist -- damit nicht unveränderlich genug für einen Index. ALTER TABLE share_views ADD COLUMN IF NOT EXISTS stunde text; CREATE UNIQUE INDEX IF NOT EXISTS share_views_einmal_je_stunde_idx ON share_views (share_id, kind, ip_hash, stunde) WHERE ip_hash IS NOT NULL AND stunde IS NOT NULL;