Sesje logowania zamiast HTTP Basic (LOG-34) #76
Reference in New Issue
Block a user
Delete Branch "feat/sesje-logowanie"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Basic nie miał wylogowania i nie dało się tego obejść: przeglądarka zapamiętuje hasło i dosyła je sama przy każdym żądaniu, więc serwer nie ma czego zapomnieć. Poprzednia próba (LOG-32) opierała się na nakłonieniu przeglądarki, żeby porzuciła zapamiętane dane — zachowaniu powszechnym, ale nigdzie nie zapisanym. Teraz to serwer decyduje, czy dana przeglądarka jest w środku, i może to cofnąć.
Trzy poziomy unieważnienia
Rozdzielone celowo, bo każdy kosztuje co innego:
Środkowy jest najważniejszy: bez niego odebranie komuś dostępu nie odbierałoby dostępu aż do wygaśnięcia sesji.
Konto administracyjne — odseparowane
Sprawdzane pierwsze i bez dotykania pliku kont. Daje to dwie rzeczy naraz:
Trzymanie jego stanu w tym samym pliku dawałoby zakleszczenie: nie da się naprawić, bo nie da się wejść. Jego odpowiednikiem „wyloguj zewsząd" jest zmiana
APP_PASSWORD. Osobny test sprawdza logowanie przy uszkodzonym pliku.Klucz wymagany, fail-closed
Usługa z kontami, ale bez klucza podpisu, nie odróżniłaby ważnej sesji od podrobionej — więc nie wstaje, i lepiej przy starcie niż przy pierwszym logowaniu człowieka. Losowanie klucza byłoby wygodne, ale wylogowywałoby wszystkich przy każdym restarcie poda: wygląda jak awaria i uczy ludzi ignorować ekran logowania.
Reszta decyzji
HttpOnly— jeden wstrzyknięty skrypt inaczej wynosi sesję. Sprawdzone na żywo: JS nie widzi ciasteczka.SameSite=Strict— obca strona nie zadziała w imieniu zalogowanego?dokad=https://obcyzamieniłby ekran logowania w narzędzie do wyłudzania hasełSet-Cookieleciałby przy każdym obrazkuWeryfikacja
21 testów na sam rdzeń podpisywania, w tym podrabianie ładunku, podpisu i klucza, ciasteczko z przyszłości, śmieci na wejściu. Reszta przepisana z Basic na sesje. Prezentacja 338 zielonych.
Sprawdzone w przeglądarce: po zalogowaniu ciasteczko jest niewidoczne dla JavaScriptu, a po wylogowaniu wejście na chronioną stronę ląduje na ekranie logowania — czyli dokładnie to, czego Basic nie potrafił.
⚠️ Wymaga
SESSION_SECRETw sekrecie —deploy→feat/sesje-logowanie.🤖 Generated with Claude Code
Basic nie miał wylogowania i nie dało się tego obejść: przeglądarka zapamiętuje hasło i dosyła je SAMA przy każdym żądaniu, więc serwer nie ma czego zapomnieć. Poprzednia próba (LOG-32) opierała się na nakłonieniu przeglądarki, żeby porzuciła zapamiętane dane — zachowaniu powszechnym, ale nigdzie nie zapisanym. Teraz to serwer decyduje, czy dana przeglądarka jest w środku, i może to cofnąć. TRZY POZIOMY UNIEWAŻNIENIA, celowo rozdzielone, bo każdy kosztuje co innego: 1. wylogowanie = skasowanie ciasteczka. Natychmiastowe, bez magazynu. 2. zmiana hasła albo skasowanie konta = odcisk poświadczenia wpisany w ciasteczko przestaje pasować. Dzieje się SAMO, bez pamiętania o tym. Bez tego odebranie komuś dostępu nie odbierałoby dostępu aż do wygaśnięcia. 3. „zamknij sesje" z ekranu kont = licznik pokolenia. Jedyny wymagający zapisu, więc jedyny opcjonalny: gdy licznika nie ma, poziomy 1 i 2 nadal działają. KONTO ADMINISTRACYJNE ODSEPAROWANE. Sprawdzane pierwsze i BEZ DOTYKANIA pliku kont, co daje dwie rzeczy naraz: konto z pliku o tym samym loginie nie przesłoni administratora, a administrator zaloguje się także wtedy, gdy plik jest uszkodzony — czyli w jedynej sytuacji, w której ktoś MUSI wejść, żeby to naprawić. Trzymanie jego stanu w tym samym pliku dawałoby zakleszczenie: nie da się naprawić, bo nie da się wejść. Jego odpowiednikiem „wyloguj zewsząd" jest zmiana APP_PASSWORD. KLUCZ WYMAGANY, FAIL-CLOSED. Usługa z kontami, ale bez klucza podpisu, nie odróżniłaby ważnej sesji od podrobionej, więc nie wstaje — i lepiej przy starcie niż przy pierwszym logowaniu człowieka. Losowanie klucza byłoby wygodne, ale wylogowywałoby wszystkich przy każdym restarcie poda: wygląda jak awaria i uczy ludzi ignorować ekran logowania. Ciasteczko HttpOnly (jeden wstrzyknięty skrypt inaczej wynosi sesję) i SameSite=Strict (obca strona nie zadziała w imieniu zalogowanego). Wylogowanie POST-em, nie odsyłaczem: pod adresem GET wystarczyłby obrazek na obcej stronie. Adres powrotu po zalogowaniu przechodzi przez sito — bez tego `?dokad=https://obcy` zamieniłby nasz ekran logowania w narzędzie do wyłudzania haseł. Kres bezczynności 8 h i twardy 30 dni. Znacznik aktywności odświeżany z progiem, inaczej Set-Cookie leciałby przy każdym obrazku i arkuszu stylów. Zdarzenia logowania w dzienniku (PRE-17). Nieudane próby są tam ważniejsze od udanych: pojedyncza nic nie znaczy, ale seria pod jednym adresem to jedyny widoczny ślad zgadywania haseł. Test pilnuje, że hasło tam nie trafia. Sprawdzone w przeglądarce: po zalogowaniu ciasteczko jest NIEWIDOCZNE dla JavaScriptu, a po wylogowaniu wejście na chronioną stronę ląduje na ekranie logowania — czyli dokładnie to, czego Basic nie potrafił. Testy: 21 na rdzeń podpisywania (w tym podrabianie ładunku, podpisu i klucza, ciasteczko z przyszłości, śmieci na wejściu), reszta przepisana z Basic na sesje. Prezentacja 338 zielonych. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>