Vývoj softwaru

Útoky založené na časování v PHP: Praktický příklad — proč je funkce `hash_equals()` důležitá

Chcete vidět reálný příklad časového útoku na API tokeny ve WordPressu/Laravelu/PHP? Zde se tím budeme zabývat, včetně tipů a osvědčených postupů pro obranu proti časovým útokům.

Mnoho vývojářů se při ověřování API klíčů, tokenů nebo jiných tajných řetězců spoléhá na jednoduché porovnání pomocí operátorů === nebo ==. Na první pohled to vypadá rozumně — má to však háček: útočníci mohou zneužít časové rozdíly při porovnávání.

Tento příspěvek popisuje realistický příklad toho, jak koncepčně probíhá časová útok.

Skutečný scénář (zjednodušený příklad)

Představte si, že interní mikroslužba přijímá požadavky s dotazovým parametrem „token“ a porovnává jej s tokenem API služby GitHub uloženým v prostředí.

Nezabezpečený kód (zjednodušeně):

// unsicher.php (vereinfachtes Beispiel)
$expected = getenv('GITHUB_API_TOKEN');

// z. B. 'V1cHt2S67DADJIm9sX9yzCc272EkSC'
$provided = $_GET['token'] ?? '';
if ($provided === $expected) {
    // Zugriff gewähren
}
                              PHP
                            

Proč je to problematické, vysvětlím v následující části.

Jak funguje časová útok?

Pokud implementace porovnání tokenu porovnává znak po znaku a při první chybě se okamžitě přeruší, trvá požadavek se správným prvním znakem v průměru o něco déle.

Správný první znak tedy v průměru vede k minimálně delší době zpracování než nesprávný první znak. Totéž platí pro druhý znak atd.

Útočník toho využije tím, že pro každou pozici otestuje všechny možné znaky, velmi často měří doby odezvy a statisticky je vyhodnocuje. Znak s největší průměrnou/relativně delší dobou je pravděpodobně správný. Takto se token krok za krokem rekonstruuje.

Proč je hash_equals() správnou volbou

PHP poskytuje funkci hash_equals(), která umožňuje porovnání řetězců v konstantním čase (constant-time comparison). Zajišťuje, že doba provedení porovnání nezávisí na společných prefixech – pokud jsou oba řetězce stejně dlouhé.

Bezpečná alternativa (pro Laravel, PHP, WordPress):

// sicher.php
$expected = getenv('GITHUB_API_TOKEN');
$provided = $_GET['token'] ?? '';
if (hash_equals($expected, $provided)) {
    // Zugriff gewähren
}
                              PHP
                            

Poznámka: Funkce hash_equals() je „nezávislá na čase“ pouze v případě, že jsou délky řetězců stejné. Osvědčeným postupem je navrhovat tokeny tak, aby měly konstantní délku (např. HMAC, UUID s pevnou délkou nebo náhodné řetězce Base64 s pevnou délkou).

Věděl jsi to? Pouze UUID-V4 je generováno zcela náhodně, a proto se často používá pro bezpečnostní tokeny. Protože neobsahuje žádné informace související s časem ani zařízením, nabízí vysokou nepředvídatelnost a chrání tak před útoky založenými na vzorcích nebo předpovědích. Právě proto je UUID-V4 preferovanou volbou, pokud jde o bezpečné identifikátory, které je obtížné uhodnout.

Další ochranná opatření — více než jen hash_equals()

  1. Konstantní délka tokenu
    Používejte tokeny s pevnou délkou, např. UUID-V4. Pokud útočník uhádne délku, není to příliš užitečné, pokud jsou samotné znaky bezpečné.
  2. Omezení frekvence
    Omezte počet požadavků na jednu IP adresu nebo jeden účet. Útoky založené na měření času vyžadují mnoho měření; omezení frekvence výrazně zvyšuje úsilí a náklady útočníka.
  3. Protokolování a monitorování
    Rozpoznávejte neobvyklé vzorce (mnoho pokusů o odhad tokenu, systematické změny určitých parametrů) a reagujte automaticky.
  4. Salt / HMAC / podpisy
    Používejte podepsané tokeny (HMAC s tajným klíčem) nebo tokeny OAuth namísto otevřeného porovnávání nezpracovaných statických klíčů.
  5. TLS/HTTPS
    Šifrování chrání komunikační kanály – sice nezabrání časovým útokům na vnitřní součásti serveru, ale je základním předpokladem.
  6. Rotace tokenů
    Krátká životnost tokenů snižuje užitnou hodnotu kompromitovaného tokenu.

Závěr

Útoky typu „timing attack“ nejsou čistě teoretickým problémem — byly zkoumány v praxi a mohou mít, zejména u veřejně přístupných koncových bodů, vážné následky. Dobrá zpráva: Pro vývojáře PHP/Laravel/WordPress je první protiopatření velmi jednoduché:

  • Nahraďte přímé porovnávání citlivých řetězců funkcí ` hash_equals()`.
  • Zajistěte konstantní délky tokenů, omezení frekvence, protokolování a bezpečnou správu tokenů.

Langmeier Backup

Zálohování pro Windows

  Koupit nyní   Vyzkoušejte zdarma

Zálohovací software pro Windows

O autorovi
Zakladatel a generální ředitel společnosti Langmeier Software
Nechci nic zbytečně komplikovat. Nechci vyvíjet ten nejlepší podnikový software. Nechci se dostat do žebříčku nejlepších technologií. O to totiž u podnikových aplikací nejde. Jde o to, aby vaše data byla bezproblémově chráněna. A jde o to, aby vše fungovalo hladce, zatímco vy si zachováte plnou kontrolu a můžete se soustředit na růst vaší firmy. Jednoduchost a spolehlivost jsou mými hlavními zásadami a každý den mě inspirují.
 
Další informace: