{
    "slug": "timing_attacks",
    "term": "Timing Attacks",
    "category": "security",
    "difficulty": "advanced",
    "short": "Side-channel attacks that infer secret values by measuring how long an operation takes — a string comparison that short-circuits on the first mismatch leaks information about the secret one character at a time.",
    "long": "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.",
    "aliases": [
        "timing side-channel",
        "constant-time comparison",
        "hash_equals",
        "side-channel attack"
    ],
    "tags": [
        "security",
        "cryptography",
        "side-channel",
        "authentication",
        "hmac"
    ],
    "misconception": "Timing attacks are not theoretical — same-datacenter or cloud-colocated attackers can measure sub-millisecond differences with enough samples to recover tokens, even with network noise.",
    "why_it_matters": "Any code that compares a secret token using == is vulnerable — HMAC verification, API key checks, and password-reset token comparison must all use hash_equals() or an equivalent constant-time function.",
    "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."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "hmac",
        "brute_force_protection",
        "crypto_common_mistakes",
        "hash_equals",
        "side_channel_attack"
    ],
    "prerequisites": [
        "hmac",
        "authentication",
        "crypto_common_mistakes"
    ],
    "refs": [
        "https://www.php.net/manual/en/function.hash-equals.php",
        "https://codahale.com/a-lesson-in-timing-attacks/"
    ],
    "bad_code": "// Vulnerable — short-circuits on first mismatch:\nif ($request->header('X-Signature') === hash_hmac('sha256', $payload, $secret)) {\n    processWebhook($payload);\n}",
    "good_code": "// Constant-time comparison:\n$expected = hash_hmac('sha256', $payload, $secret);\n$received = $request->header('X-Signature') ?? '';\nif (!hash_equals($expected, $received)) {\n    throw new InvalidSignatureException();\n}\nprocessWebhook($payload);",
    "example_note": "The bad example uses === which short-circuits — an attacker measuring webhook response times can recover the HMAC secret. hash_equals() always compares all bytes, producing identical timing regardless of where strings differ.",
    "quick_fix": "Replace == or strcmp() with hash_equals($known_good, $user_supplied) for all token and HMAC comparisons",
    "severity": "high",
    "effort": "low",
    "created": "2026-04-10",
    "updated": "2026-04-10",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/timing_attacks",
        "html_url": "https://codeclaritylab.com/glossary/timing_attacks",
        "json_url": "https://codeclaritylab.com/glossary/timing_attacks.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Timing Attacks](https://codeclaritylab.com/glossary/timing_attacks) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/timing_attacks"
            }
        }
    }
}