Preventing Timing Attacks

1. Understanding Timing Attack Vectors

VectorLeak
String compare (==)Returns early on mismatch — reveals prefix
User existenceDifferent response times for valid vs invalid user
Cache hitsFaster response reveals state
DB queryIndex hit vs miss

2. Implementing Constant-Time Comparisons

Example: Per-language API

Node:    crypto.timingSafeEqual(a, b)            // equal-length Buffers
Python:  hmac.compare_digest(a, b)
Go:      subtle.ConstantTimeCompare(a, b) == 1
Java:    MessageDigest.isEqual(a, b)
Ruby:    ActiveSupport::SecurityUtils.secure_compare

3. Using Secure String Comparison

Warning: Even constant-time compare leaks length. Hash both sides (HMAC with random key) before compare to mask length.

4. Handling Username Enumeration

EndpointMitigation
LoginSame error for unknown user vs wrong password
SignupGeneric "If account exists, check email"
Password resetAlways respond 200; send email only if exists
TimingHash dummy password even when user not found

5. Implementing Consistent Response Times

Example: Pad to fixed minimum

async function login(email, pw) {
  const start = Date.now();
  const user = await User.findByEmail(email);
  const hash = user?.passwordHash ?? "$argon2id$v=19$m=65536,t=3,p=4$xxxxxx";
  const ok = await argon2.verify(hash, pw);
  // Pad to min 300ms
  const elapsed = Date.now() - start;
  if (elapsed < 300) await new Promise(r => setTimeout(r, 300 - elapsed));
  return ok && user;
}

6. Using Dummy Operations

Perform equivalent CPU work (e.g., dummy hash) when account does not exist so request timing is indistinguishable.

7. Handling Cache Timing Attacks

MitigationDetail
Cache by categorySame cache key class for valid/invalid
Random delayAdd jitter to mask cache hits
Pre-warmAvoid cold-vs-warm signal

8. Implementing Response Time Randomization

Warning: Random delay alone is statistically defeatable. Combine with constant-time + dummy ops.

9. Using Rate Limiting to Mask Timing

Aggressive per-IP rate limits prevent attacker from collecting enough samples to extract a timing signal.

10. Preventing Information Leakage

SourceMitigation
Error messagesGeneric, identical for similar failures
HTTP statusSame code (e.g., always 401, never 404)
Response sizePad responses
LogsDon't echo sensitive input