Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: ProsteMajkl 07. 01. 2021, 04:59:13
-
Dobrý den,
otázka pro PHPáře, když ochraňuji POST/GET formuláře, generuji CSRF tokeny.
Má otázkní zní, proč se při následné kontrole nedoporučuje používat == nebo ===, ale ideálně hash_equals?
Fungují všechny tři varianty, ale pokud se nepletu, hash_equals je nejbezpečnější :)
Děkuji za objasnění.
PS: nejsem úplný odborník, proto vás žádám o "lidské" vysvětlení :)
-
Operátor == dělá implicitní konverzi typu a tím potažmo i hodnoty. Výraz 0 == "asd" je true.
Operátor === testuje typ i hodnotu.
https://www.php.net/manual/en/language.types.type-juggling.php (https://www.php.net/manual/en/language.types.type-juggling.php)
https://www.php.net/manual/en/types.comparisons.php (https://www.php.net/manual/en/types.comparisons.php)
Naivní porovnávání stringů je postupné procházení a testování obsahu dokud se nenarazí na rozdíl (pak nejsou shodné) nebo na konec (jsou shodné). Při dostatečně přesném měření tak můžeš zjistit, jak daleko porovnávání došlo a kde je rozdíl, který potřebuješ upravit. hash_equals trvá vždycky stejně dlouho, pokud ho použiješ správně - viz dokumentace.
https://www.php.net/manual/en/function.hash-equals.php (https://www.php.net/manual/en/function.hash-equals.php)
-
protože:
> var_dump(0 == "0e48a24b70a0b37653552b996af51739");
bool(true)
hash_equals pak brání i dalším útoků typu timing attack.
-
V PHP8 sa to uz menilo (https://www.root.cz/clanky/php-8-trojnasobny-vykon-diky-jit-a-uzitecne-novinky-pro-programatory/#h28). Vid aj:
$ php -v
PHP 8.0.0 (cli) (built: Nov 27 2020 11:28:33) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
with Zend OPcache v8.0.0, Copyright (c), by Zend Technologies
$ php -r 'var_dump(0 == "0e48a24b70a0b37653552b996af51739");'
bool(false)
$
-
ano, sesumírovali to v https://www.php.net/manual/en/migration80.incompatible.php, konečně kontrolují jestli druhá strana je číslo. Kromě toho se opravil i dlouholetý problém s 0 == strcmp. Od php 8 krom toho hash_equals akceptuje jako vstup pouze string, tím zamezí problémům typu předání v postu/get pole.
To nic nemění na tom, že hash_equals tady je od 5.6 a je právě určen pro porovnávání tokenů a hashů, bude na tenhle use case testování, zamezuje řadě jiných útoků, nejen chybnému přetypování.
Time attack je třeba pěkně vysvětlen tady https://blog.ircmaxell.com/2014/11/its-all-about-time.html, to jen pro ilustraci, že i === nemusí být vždy bezpečné.
-
Všem moc děkuji za objasnění. Teď už chápu.