← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Timing Attacks

security CWE-208 Advanced

Also Known As

timing side-channel constant-time comparison hash_equals side-channel attack

TL;DR

Side-channel attacks that infer secret values by measuring how long an operation takes — a string comparison that short-circuits on the first mismatch leaks information about the secret one character at a time.

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

Even hash_equals() leaks timing info if the two strings have different byte lengths — always compare fixed-length hashes (e.g. hash the user input before comparing) so both inputs are the same length.

Common Misconception

Timing attacks are not theoretical — same-datacenter or cloud-colocated attackers can measure sub-millisecond differences with enough samples to recover tokens, even with network noise.

Why It Matters

Any code that compares a secret token using == is vulnerable — HMAC verification, API key checks, and password-reset token comparison must all use hash_equals() or an equivalent constant-time function.

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

💡 Note
The bad example uses === which short-circuits — an attacker measuring webhook response times can recover the HMAC secret. hash_equals() always compares all bytes, producing identical timing regardless of where strings differ.
✗ Vulnerable
// Vulnerable — short-circuits on first mismatch:
if ($request->header('X-Signature') === hash_hmac('sha256', $payload, $secret)) {
    processWebhook($payload);
}
✓ Fixed
// Constant-time comparison:
$expected = hash_hmac('sha256', $payload, $secret);
$received = $request->header('X-Signature') ?? '';
if (!hash_equals($expected, $received)) {
    throw new InvalidSignatureException();
}
processWebhook($payload);

Added 10 Apr 2026
Views 13
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 2 pings S 2 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 2 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
SEMrush 3 ChatGPT 1 Perplexity 1 Unknown AI 1 Google 1 Ahrefs 1 Qwen 1
crawler 9
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Replace == or strcmp() with hash_equals($known_good, $user_supplied) for all token and HMAC comparisons
🔗 Prerequisites
🔍 Detection Hints
=== or == comparing hash_hmac(), token strings, or API keys directly
Auto-detectable: ✓ Yes semgrep phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line
CWE-208 CWE-697

✓ schema.org compliant