Timing Attacks
debt(d5/e1/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and phpstan as the tools that catch the pattern of == or === comparing hash_hmac() outputs or token strings. These are not default linters but specialist SAST tools that require deliberate configuration, placing this squarely at d5.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix is explicit: replace == or strcmp() with hash_equals($known_good, $user_supplied). This is a single-call swap at each comparison site, so e1 is the correct anchor, though multiple call sites may exist independently.
Closest to 'localised tax' (b3). The fix applies at each token/HMAC comparison point rather than spreading across the whole architecture. It is a recurring tax wherever secrets are compared, but each site is self-contained and the rest of the codebase is unaffected, keeping burden at b3.
Closest to 'serious trap' (t7). The misconception field states that developers widely believe timing attacks are theoretical or impractical, but in reality same-datacenter or cloud-colocated attackers can exploit sub-millisecond differences with enough samples. Additionally, the common_mistakes show that even hash_equals() has a subtlety around length mismatches that can still leak information, contradicting the assumption that switching to hash_equals() is fully sufficient without normalising lengths. This combination of 'looks safe but isn't' plus 'the obvious replacement also has a gotcha' lands at t7.
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.
Avoid When
- Describing attacks on cryptographic algorithms themselves (e.g., breaking AES or RSA)—use 'side-channel attacks' or 'cryptanalysis' instead, as timing attacks on crypto primitives are a specific subset requiring different mitigations.
- Referring to performance differences in legitimate application logic (e.g., database queries that vary by result size)—timing attacks specifically exploit information leakage from security-sensitive operations, not normal variance.
- Discussing network latency or bandwidth as a security concern—timing attacks require measurement of operation duration, not network conditions.
- Analyzing brute-force attacks that succeed through sheer computational cost—timing attacks rely on differential timing signals to narrow the search space, not raw speed.
When To Use
- You're reviewing code that compares HMAC tokens, API keys, or session identifiers using standard string comparison operators — switch to constant-time comparison immediately to block character-by-character recovery.
- You're designing a password reset or account recovery flow where an attacker can submit many guesses and measure response times — use constant-time token validation to eliminate the timing side-channel.
- You're assessing whether a legacy authentication system is vulnerable to side-channel attacks, especially in internal networks or cloud environments where an attacker has low-latency access to the server.
- You're implementing signature or HMAC verification for APIs or webhooks — always use a constant-time comparison function to prevent attackers from forging valid signatures by exploiting timing differences.
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);