Vulnerable
Early-exit comparison
def check_password(guess, secret):
for i in range(len(secret)):
if guess[i] != secret[i]:
# exits immediately!
return False
# each match adds delay
time.sleep(0.01)
return True
Each correct character adds a measurable delay before the function exits. An attacker can probe position by position, picking the character that made the server respond slowest.
Secure
Constant-time comparison
import hmac
# Always compares every byte —
# no early exit, no timing leak.
result = hmac.compare_digest(
guess, secret
)
Takes the same amount of time regardless of how many characters match. The attacker learns nothing from timing because the function always does the same work.
How the attack works
1
Probe position 0
Try every possible character (a–z, 0–9) and measure response time for each
→
2
Find the slowest
The character that took longest matched — the server kept comparing longer
→
3
Repeat per position
Lock in found characters, probe the next position. 36 guesses × 6 chars = 216 total
→
!
Password cracked
Without ever brute-forcing all combinations (36⁶ = 2.1 billion)
Server configuration
●●●●●●
5ms (subtle)150ms (obvious)
Send a guess
Response log
Send some guesses above to see response times...
0
Requests sent
0 / 6
Chars found
0.0s
Time elapsed
—
Requests saved
_ _ _ _ _ _
Attack log
Press "Start timing attack" to begin...