Za předpokladu, že již máte web, který implementuje všechny standardní přihlašovací údaje, jaký je správný a nejbezpečnější způsob, jak uživatelům umožnit automatické přihlášení po určitou dobu (řekněme 30 dní)? Toto časové období by mělo být přísně vymáháno; tj. nemyslím si, že by platným řešením bylo poskytnout cookie datum vypršení platnosti a doufat, že prohlížeč uživatele jej včas odstraní.
Podrobnosti o existujícím přihlašovacím systému:
Existuje mnoho příkladů a mnoho zjevných bezpečnostních nedostatků. Jako cílový jazyk použijeme PHP), ale pojmy by se měly vztahovat na jakýkoli jazyk.
Moje odpověď má dvě části:
Za prvé, za předpokladu, že váš model hrozby se nebojí o vystavení souborů cookie na straně klienta , můžete vygenerovat a uložit neteř na straně serveru, hash to s uživatelské jméno a další informace (např. IP klienta, název počítače, časové razítko, podobné věci) a odešlete je do souboru cookie. Nonce by měl být uložen v databázi spolu s datem expirace a oba by se měli zkontrolovat, jakmile se cookie vrátí.
Měl by to být pouze „pamětní“ soubor cookie, NENÍ soubor cookie relace - tj. Když tento soubor cookie získáte bez relace, znovu zadejte nový soubor cookie pravidelné relace. Také si všimněte, že stejně jako soubor cookie relace by měl být doručován pouze prostřednictvím protokolu https a pomocí atributů secure
a httpOnly
, a samozřejmě mít soubor cookie správně nastaven atd.
Zadruhé, pro uživatele, kteří si pamatovali, byste měli (pravděpodobně v závislosti na citlivosti) vyvolat proces opětovné autentizace pro určité citlivé operace. To znamená, že někdy budou muset znovu vložit své heslo, ale jen zřídka a pouze pro citlivé operace. Tím se zabrání útokům, jako je CSRF a sdílení sdílené plochy.
Napsal jsem velkou délku o zabezpečená přihlášení a zaškrtávací políčka "pamatujte si mě" . Přijatá odpověď není špatná, ale tvrdil bych, že je to v jednom ohledu o něco složitější, než je třeba, a zanedbává oblast, kde je potřeba o něco složitější.
generovat a ukládat nonce na straně serveru, hash, který s uživatelským jménem a dalšími informacemi (např. ip klienta, computername, timestamp, podobné věci), a poslat to v cookie. Nonce by měl být uložen v databázi spolu s datem expirace a oba by se měli zkontrolovat, jakmile se cookie vrátí.
Implementace, která nevystavuje klientovi žádné informace, by tedy mohla vypadat jako ...
// Storage:
setcookie(
'rememberme',
hash_hmac('sha256', $username . $_SERVER['REMOTE_ADDR'], $storedNonce),
time() + 8640000 // 100 days, for example
);
// Validation:
$valid = hash_equals(
$_COOKIE['rememberme'],
hash_hmac('sha256', $username . $_SERVER['REMOTE_ADDR'], $storedNonce)
);
Zde je zřejmé omezení, že pokud se změní vaše IP adresa (nebo jiné informace), váš cookie je zbytečný. Někteří to považují za dobrou věc, vidím to jako zbytečně nepřátelské vůči použitelnosti pro uživatele Tor.
Výše uvedenou nabídku můžete určitě interpretovat tak, že znamená něco jiného, jako je například token JSON chudého člověka. Cookies HTTP jsou však omezeny na 4 kB na doménu. Prostor je prémiový.
Další problém: Kolik informací vytéká váš databázový dotaz o vaší aplikaci? (Ano, mluvím o vedlejších kanálech.)
random_bytes()
(PHP 7.0+ nebo přes random_compat ), base64 jej zakódujte do 12. Toto bude použito pro vyhledávání v databázi.$lookup
A hash('sha256, $validator)
do databáze; samozřejmě spojené s konkrétním uživatelským účtem.$lookup . $validator
V HTTP cookie uživatele (např. rememberme
).$lookup
A $validator
.$lookup
; je to v pořádku, pokud je zde načasovaný vedlejší kanál.hash_equals($row['hashedValdator'], hash('sha256', $validator))
.TRUE
, přiřaďte aktuální relaci k příslušnému uživatelskému účtu. Jaké vedlejší kanály jsou zmírněny?
Nejvýznamněji: zmírňuje dopad úniků časovacích informací na operaci porovnávání řetězců použitou při vyhledávání v databázi.
Pokud jste implementovali naivní autentizaci náhodným tokenem, mohl by útočník poslat mnoho požadavků, dokud nenajde platný autentizační token pro uživatele. (Pravděpodobně by si nemohli vybrat, kterou oběť se předstírají.)
$validator
, Ale prostý text pro hash je uložen v cookie. Protože vstup je vysoká entropická hodnota, je nepravděpodobné, že by při hledání brutální síly přineslo nějaké výsledky. (To také snižuje potřebu např. Bcrypt.)Tato strategie je implementována v Gatekeeper .
To je zajímavá otázka. Začnu tím, že řeknu, že si nejsem jistý, že se to dá udělat bez nějakého oslabení bezpečnosti aplikace, ale pak v závislosti na webu, který lze považovat za kompromis.
Takže jeden přístup by mohl být
Databáze stavu relace bude muset zaznamenat čas, kdy je nastaven token, a dobu, po kterou by měl být zapamatován, aby mohl porovnat prezentovaný token.
Když se uživatel přihlásí do aplikace, má zaškrtávací políčko, které mu umožňuje zůstat přihlášeni (ideálně s rozsahem časových období, které si uživatel může vybrat)
Když je nastaven token relace, použije se toto časové období jako doba platnosti souboru cookie. Při následných návštěvách bude cookie předložena aplikaci a server bude muset zkontrolovat, zda je stále platný (tj. Nebylo dosaženo doby vypršení platnosti funkce zapamatovat si mě). Pokud je token stále platný, je s uživatelem zacházeno jako s ověřeným, pokud ne, token je vymazán a uživatel je přesměrován na přihlašovací obrazovku.
Problémy s tímto přístupem. Sdílené prohlížeče by znamenaly, že je možný neoprávněný přístup.
Neautorizovaný přístup k webu bude moci získat také kdokoli, kdo může získat přístup k souboru cookie (buď prostřednictvím zranitelnosti na webu, problémem s prohlížečem nebo malwarem umístěným na počítači). Jedním z běžných návrhů, jak to zmírnit, je pokus o navázání cookie na zdrojovou IP adresu (samozřejmě zašifrovanou nebo uloženou na serveru), která je kontrolována, když uživatel prezentuje cookie, ale to způsobuje problémy s velkým podnikovým prostředím, kde může uživatel přijít z několika IP adres, a také mohou být citlivé na spoofing.
Chcete-li soubor cookie smazat, nemusíte záviset na prohlížeči, web musí zkontrolovat datum vypršení platnosti souboru cookie.
Ve skutečnosti, aby to bylo bezpečné, řekl bych, že to je pravděpodobně to, co budete muset udělat, tak jako tak, protože byste chtěli nastavit datum vypršení platnosti jako součást hodnoty souboru cookie a zašifrovat jej spíše než spoléhat na vlastnost expirace prostého textu samotného souboru cookie.
A opravdu byste chtěli označit cookie jako zabezpečené a použít sekundární cookie po celou dobu jednotlivé relace, nebo chránit celou relaci (nejen proces přihlášení) pomocí SSL, abyste zabránili ukradení cookie z drátu a používá je neoprávněnou stranou.
Tento článek popisuje přístup, který brání proti krádeži souborů cookie a hádání ID relací:
Jako další bezpečnostní opatření se doporučuje, aby kritické akce, jako je změna přihlašovacích údajů nebo platba za věci, vyžadovaly heslo, pokud byl uživatel autentizován pouze pomocí souboru „zapamatovat si mě“.
Databázová tabulka, která obsahuje ID uživatele a tokeny, také obsahuje datum vypršení platnosti tokenů. Může také obsahovat uživatelského agenta a IP adresu, takže je musí útočník také replikovat. Všechny tokeny by se měly ukládat pouze jako hash, protože v zásadě fungují jako hesla a umožňují útočníkovi, který získal databázi, přihlásit se.
Vytvořil jsem kázková implementace pro PHP.