flawopen.com/Vulnerabilities/Timing Attacks & Constant-Time Comparison

Timing Attacks & Non-Constant-Time Comparisons

Medium / Subtle CWE-208 Cryptography & Auth
ELI5 — The Combination Lock Click Sound

Imagine a safe with a 4-digit code. When you turn the dial to the first correct number, the lock makes a tiny metallic 'click' sound. It takes 1 millisecond longer to click than a wrong number. By listening with a sensitive microphone, a safecracker guesses the first digit, then the second, cracking the entire safe in minutes instead of trying 10,000 combinations. In timing attacks, standard string equality (==) stops comparing the moment it finds a mismatch, leaking the secret letter by letter based on how many nanoseconds the server takes to reply.

Target: API authentication tokens, webhook HMAC signatures, password verification
Vector: Measuring response latency across thousands of requests (side channel)
Impact: Recovery of secret tokens, webhook signature forging, authentication bypass
Remediation: Constant-time comparison functions (hmac.compare_digest)

The Mechanism & Root Cause

Standard string equality operators (== in Python/JS/Java) are optimized for speed: they compare characters one by one from left to right and return False on the very first mismatch (early exit). If the first byte matches, the comparison runs slightly longer. By measuring statistical round-trip latency, attackers deduce secret strings one byte at a time.

webhook_auth.py (Vulnerable Early-Exit)Vulnerable
# VULNERABLE: '==' returns immediately upon the first wrong character
def verify_webhook_signature(received_sig, expected_sig):
    # If the first character matches, comparison takes ~50ns longer
    # Attackers measure latency to brute-force the signature character-by-character
    if received_sig == expected_sig:
        return True
    return False
webhook_auth.py (Hardened Constant-Time)Hardened
# HARDENED: hmac.compare_digest compares all bytes regardless of mismatches
import hmac

def verify_webhook_signature_safe(received_sig, expected_sig):
    # Runs in constant time proportional only to string length, never content
    if hmac.compare_digest(str(received_sig), str(expected_sig)):
        return True
    return False

The Attack & Exploit Sequence

Defensive Engineering & Prevention Rules

Explore related security topics and post-mortems: Complete Security Directory →