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

Cache-Timing Side-Channel Attacks

security PHP 5.6+ Advanced
debt(d5/e3/b3/t9)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep as the tool, which catches the pattern of == or === comparison of HMAC signatures and tokens. This is a specialist SAST tool, not a default linter or compiler error — a developer must deliberately configure and run semgrep to catch these comparisons. The cache-timing leak variant (response timing revealing cache hits) is harder still and likely d7, but the dominant == comparison pattern lands at d5.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is to replace == with hash_equals() for security-sensitive comparisons — that's a targeted pattern replacement. Common mistakes show a consistent pattern: swap == for hash_equals(), use password_verify() instead of raw ==, use timing-safe base64 decoding. Each fix is a small, localised substitution within one file or function, not a cross-cutting architectural change. Slightly more than a one-liner (e1) because multiple call sites may need updating, but well within e3.

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

Closest to 'localised tax' (b3). The applies_to scope is web and api contexts, and the fix is a coding pattern (use hash_equals() consistently) rather than an architectural commitment. Once developers know the rule, enforcement is localised to security-sensitive comparison points. It doesn't reshape the whole codebase or impose a persistent productivity tax on unrelated work streams — it's a discipline applied at specific, identifiable spots.

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

Closest to 'catastrophic trap' (t9). The misconception field states exactly this: developers believe millisecond timing differences are too small to exploit, but statistical analysis over thousands of requests reveals sub-microsecond differences that make attacks practical even from the same data centre. The why_it_matters section confirms the 'obvious' approach (== comparison) is always wrong for security tokens — it leaks character-by-character prefix information. A competent developer who doesn't know this concept will almost certainly reach for == as the natural equality check, making this a catastrophic cognitive trap.

About DEBT scoring →

Also Known As

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

TL;DR

Attacks that infer secret information from response time differences — cached responses arrive faster than uncached ones, leaking whether a resource exists or a secret was correct.

Explanation

Timing attacks exploit measurable differences in execution time to infer secrets. Cache timing: an attacker queries a resource and measures response time — a cache hit is faster than a miss, revealing whether the resource was recently accessed by another user. This leaks: whether a user exists (cached profile = faster response), whether a secret token was used, or whether a URL was recently visited. The classic timing attack is string comparison: == completes early on first mismatch, leaking how many characters were correct. Mitigations: hash_equals() for constant-time comparison, random delays, and careful cache key design.

Common Misconception

Millisecond timing differences are too small to exploit — over thousands of requests, statistical analysis reveals timing differences of less than 1 microsecond; timing attacks are practical from the same data centre.

Why It Matters

A PHP string comparison using == leaks how many leading characters of a CSRF token match — an attacker can brute-force a token one character at a time, reducing the search space from 62^32 to 62*32.

Common Mistakes

  • == for comparing HMAC signatures, CSRF tokens, or API keys — use hash_equals().
  • Cache keys that include user IDs making timing leaks about user activity.
  • Password comparison without timing safety — password_verify() is timing-safe, raw == is not.
  • Not using constant-time base64 decoding for token comparison.

Code Examples

✗ Vulnerable
// Timing-vulnerable token comparison:
if ($submittedToken === $storedToken) {  // Fails fast on first mismatch
    // Attacker times thousands of requests:
    // 'a...' takes 0.1ms — first char wrong
    // 'sk1..' takes 0.3ms — first 3 chars right!
    // Can brute-force character by character
    allowAccess();
}
✓ Fixed
// Constant-time comparison — no timing information leaked:
if (hash_equals($storedToken, $submittedToken)) {
    // Same time regardless of how many chars match
    allowAccess();
}

// For HMAC verification:
$expected = hash_hmac('sha256', $payload, $secretKey);
if (!hash_equals($expected, $providedMac)) {
    throw new InvalidSignatureException();
}

// password_verify() is also constant-time:
if (!password_verify($input, $storedHash)) {
    throw new AuthenticationException();
}

Added 16 Mar 2026
Edited 22 Mar 2026
Views 27
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 1 ping F 0 pings S 0 pings S 3 pings M 0 pings T 0 pings W 1 ping T 2 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 1 ping S
Amazonbot 7 Google 5 Perplexity 4 ChatGPT 4 Unknown AI 3 SEMrush 2 Ahrefs 1
crawler 22 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Use hash_equals() for all security-sensitive comparisons — cache timing attacks exploit microsecond differences in response time to infer whether a hash prefix matches
📦 Applies To
PHP 5.6+ web api
🔗 Prerequisites
🔍 Detection Hints
== or === comparison of HMAC signatures tokens; response caching that reveals whether content was cache hit based on timing
Auto-detectable: ✓ Yes semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✓ Auto-fixable Fix: Low Context: Function
CWE-208 CWE-203

✓ schema.org compliant