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

Timing Attack

Security CWE-208 OWASP A2:2021 CVSS 5.9 PHP 5.6+ Advanced
debt(d5/e1/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and psalm as tools, both of which are specialist static analysis tools that can detect `===` or `==` comparisons of tokens/HMACs in authentication contexts. This is not caught by a compiler or default linter, but is within reach of a configured SAST rule — matching d5 exactly.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix explicitly states: replace security-sensitive string comparisons with hash_equals($known, $user_input). This is a direct one-for-one function substitution at each call site, making it e1. The only caveat is 'all' comparisons must be found, but each fix individually is a single-line swap.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The issue applies to authentication, CSRF, and HMAC comparison points — a bounded set of security-sensitive locations. It doesn't permeate every file or define the system's architecture, but developers working on auth/security components pay a recurring cost of remembering to use hash_equals everywhere. Slightly above b1 because it recurs across all auth-related code, but doesn't slow down unrelated workstreams.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field directly states that developers believe microsecond timing differences are too small to matter over the internet — this is the canonical wrong belief. The 'obvious' instinct is to use `===` (the idiomatic PHP equality operator) for comparing strings, which is exactly wrong for secrets. The statistical averaging technique that makes remote timing attacks viable contradicts most developers' intuition about network noise, making this a serious cognitive trap justifying t7.

About DEBT scoring →

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

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); }

Added 15 Mar 2026
Edited 31 Mar 2026
Views 79
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 6 pings F 1 ping S 6 pings S 1 ping M 2 pings T 3 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 2 pings T 2 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 17 Perplexity 9 Amazonbot 9 ChatGPT 6 Google 6 Unknown AI 4 Ahrefs 4 Claude 2 SEMrush 2 PetalBot 2 Bing 1 Meta AI 1
crawler 59 crawler_json 3 pre-tracking 1
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


✓ schema.org compliant