Timing Attacks
Also Known As
TL;DR
Explanation
A timing attack exploits the fact that standard string comparison (== or strcmp) returns early as soon as a mismatch is found — comparing 'abc' against 'xyz' takes less time than comparing 'abc' against 'abd'. An attacker who can make many requests and measure response times can recover a secret (HMAC token, API key, password reset token) one character at a time by submitting guesses and choosing the one that takes longest. PHP's hash_equals() performs constant-time comparison — it always inspects every byte regardless of where the first difference occurs, eliminating the timing signal. password_verify() is already constant-time. The attack is especially realistic for HMAC signature verification, API key comparison, and password reset token validation where the secret is a fixed-length string. Network jitter limits practical exploitation over the internet, but server-local or same-datacenter attacks are very feasible.
Watch Out
Common Misconception
Why It Matters
Common Mistakes
- Using === or == to compare HMAC signatures or API tokens — both short-circuit and leak timing information.
- Using strcmp() for security-sensitive comparisons — also non-constant-time.
- Comparing tokens of different lengths with hash_equals() — the function returns false immediately for length mismatches in some implementations; normalise length before comparing or use a fixed-length hash of both sides.
Code Examples
// Vulnerable — short-circuits on first mismatch:
if ($request->header('X-Signature') === hash_hmac('sha256', $payload, $secret)) {
processWebhook($payload);
}
// Constant-time comparison:
$expected = hash_hmac('sha256', $payload, $secret);
$received = $request->header('X-Signature') ?? '';
if (!hash_equals($expected, $received)) {
throw new InvalidSignatureException();
}
processWebhook($payload);