hash_equals
funkcja
Porównuje dwa ciągi znaków w sposób odporny na ataki czasowe (timing-safe). Używaj zamiast === do porównywania tokenów CSRF, podpisów i innych sekretów.
hash_equals(string $known_string, string $user_string): bool
hash_equals porównuje dwa ciągi w stałym czasie — niezależnie od miejsca pierwszej różnicy. Operator === może przerywać porównanie przy pierwszej niezgodności (short-circuit), ujawniając przez czas odpowiedzi ile znaków zgadza się od lewej. Atakujący mierzący czas mógłby stopniowo odgadywać token — to atak czasowy (timing attack).
Używaj hash_equals zawsze gdy porównujesz sekrety kryptograficzne: tokeny CSRF, klucze API, podpisy HMAC. Pierwszy argument to ciąg znany (z sesji/bazy), drugi to ciąg od użytkownika.
<?php
declare(strict_types=1);
// Ochrona CSRF — porównanie tokenów:
$tokenZSesji = $_SESSION['csrf_token'] ?? '';
$tokenZFormularza = $_POST['csrf_token'] ?? '';
// ✅ Bezpieczne — timing-safe:
if (!hash_equals($tokenZSesji, $tokenZFormularza)) {
http_response_code(403);
exit('Nieprawidłowe żądanie.');
}
// ❌ Podatne na timing attack:
// if ($tokenZSesji !== $tokenZFormularza) { ... }
// Porównanie podpisu HMAC:
$oczekiwany = hash_hmac('sha256', $wiadomosc, $klucz);
$otrzymany = $_POST['signature'] ?? '';
$ok = hash_equals($oczekiwany, $otrzymany); // bool(true) lub bool(false)