Kolik stojí heslo na skromném hardwaru
Stránky statistik tu lze chránit heslem. Hashování tohoto hesla je jediná operace v této službě, která má být pomalá – právě díky tomu je útok na ukradený hash drahý. Otázka zní, jak pomalá, na tomto hardwaru.
Měřeno na stroji, na kterém tento web běží, PHP 8:
PASSWORD_DEFAULT | 560 ms | (odpovídá cost 12) |
| cost 12 | 595 ms | |
| cost 11 | 277 ms | |
| cost 10 | 138 ms |
Parametr cost u bcryptu je exponent: každý krok práci zdvojnásobí. Měření ukazují přesně toto zdvojnásobení, což je dobré znamení, že do toho nic jiného nezasahuje.
Proč je tu výchozí hodnota špatnou volbou
PHP zvýšilo výchozí cost bcryptu z 10 na 12. Na stolním serveru je to rozumné vylepšení – jde o několik desítek milisekund. Na skromném hardwaru je to přes půl sekundy čistého procesorového času, a to na stroji, který zároveň kreslí obrázky počítadel pro všechny ostatní.
Půl sekundy na každé přihlášení je špatné samo o sobě. Horší je to jako pozvánka: přihlašovací endpoint může volat kdokoli a každé volání spotřebuje 560 ms procesoru, který obsluhuje celý web. Z ověřování hesla se tak stává nejlevnější dostupná plocha pro útok odepřením služby.
Proto je cost pevně nastaven na 10, místo aby se ponechal výchozí. Je to záměrně slabší než to, co dnes volí PHP, a má se to říct otevřeně, ne zamlčet: útok na hash s cost 10 je čtyřikrát levnější než na hash s cost 12. Vyvažuje to to, co heslo skutečně chrání – viditelnost stránky s počty návštěv, ne účet, ne peníze, ne identitu. Není za ním nic, co by se dalo převzít.
Část, kterou je snadné přehlédnout
PASSWORD_DEFAULT je záměrně proměnlivá hodnota. Kód napsaný před lety, který ji používá, bude s každou aktualizací PHP potichu pomalejší – stejný zdrojový kód, stejný vstup, několikanásobná doba běhu. Tak je to zamýšleno a pro většinu softwaru je to správně.
Špatně je to jen tehdy, když to stroj neunese, a nic neupozorní, když to neunese. Aktualizace proběhne, testy projdou, stránka dál funguje. Jen trvá o půl sekundy déle a na to číslo se nikdo nepodívá, dokud ho nezačne měřit.