Timing Attack
Also Known As
time-based side channel
timing side channel
response time attack
TL;DR
Measuring how long a comparison takes reveals information about secret values — use hash_equals() to prevent it.
Explanation
A timing attack exploits the fact that string comparison operators (===, strcmp) return early on the first mismatched character, so comparing a correct token takes slightly longer than an incorrect one. By making thousands of requests and measuring response times, an attacker can determine the correct token one character at a time. hash_equals() prevents this by always taking the same time regardless of where the strings differ. Always use it when comparing tokens, HMAC signatures, and CSRF values.
How It's Exploited
# Measure response time for different token prefixes
# Correct prefix → takes slightly longer → reveals chars one by one
# Requires many requests and statistical analysis but works against == comparison
# Correct prefix → takes slightly longer → reveals chars one by one
# Requires many requests and statistical analysis but works against == comparison
Common Misconception
✗ Timing differences of microseconds are too small for attackers to measure over the internet. Statistical timing attacks average thousands of measurements to filter out network jitter — even millisecond differences in HMAC comparison are exploitable remotely.
Why It Matters
Even microsecond differences in response time can reveal whether a guessed secret is correct, allowing an attacker to recover a password or token character by character.
Common Mistakes
- Using === to compare password hashes, HMACs, or tokens — exits early on first byte mismatch.
- Using strcmp() which also short-circuits and has additional issues with null bytes.
- Not using hash_equals() in PHP for all secret comparisons.
- Applying timing-safe comparison only to the final comparison but not to intermediate validation steps.
Avoid When
- Never use === or == to compare HMAC signatures, API tokens, or password hashes — both short-circuit on the first differing byte.
- Do not compare secrets with strcmp() or strncmp() — they are not constant-time.
When To Use
- Use hash_equals() for all security-sensitive string comparisons — it runs in constant time regardless of where strings differ.
- Use password_verify() for password checks — it uses constant-time comparison internally.
Code Examples
✗ Vulnerable
// === exits on first mismatch — reveals partial token via timing
if (\$_GET['token'] === \$secretToken) { grantAccess(); }
✓ Fixed
// hash_equals() — constant-time comparison regardless of where mismatch occurs
if (hash_equals(\$secretToken, \$_GET['token'] ?? '')) {
grantAccess();
}
// For password verification — always use password_verify (also constant-time)
if (password_verify(\$input, \$storedHash)) { /* authenticated */ }
// Timing-safe HMAC comparison for API signatures
\$expected = hash_hmac('sha256', \$requestBody, \$secret);
\$provided = \$_SERVER['HTTP_X_SIGNATURE'] ?? '';
if (!hash_equals(\$expected, \$provided)) { abort(401); }
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
31 Mar 2026
Views
43
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
Amazonbot 9
Perplexity 7
ChatGPT 6
Google 5
Unknown AI 4
Ahrefs 2
Also referenced
How they use it
crawler 31
crawler_json 1
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟠 High
⚙ Fix effort: Low
⚡ Quick Fix
Replace all security-sensitive string comparisons with hash_equals($known, $user_input) — it always takes constant time
📦 Applies To
PHP 5.6+
web
api
cli
🔗 Prerequisites
🔍 Detection Hints
$token === $stored or $hmac == $computed in authentication or CSRF token verification context
Auto-detectable:
✓ Yes
semgrep
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Low
✓ Auto-fixable
Fix: Low
Context: Line
CWE-208