{
    "slug": "timing_attack",
    "term": "Timing Attack",
    "category": "security",
    "difficulty": "advanced",
    "short": "Measuring how long a comparison takes reveals information about secret values — use hash_equals() to prevent it.",
    "long": "A timing attack exploits the fact that string comparison operators (===, strcmp) return early on the first mismatched character, so comparing a correct token takes slightly longer than an incorrect one. By making thousands of requests and measuring response times, an attacker can determine the correct token one character at a time. hash_equals() prevents this by always taking the same time regardless of where the strings differ. Always use it when comparing tokens, HMAC signatures, and CSRF values.",
    "aliases": [
        "time-based side channel",
        "timing side channel",
        "response time attack"
    ],
    "tags": [
        "cryptography",
        "side-channel",
        "authentication"
    ],
    "misconception": "Timing differences of microseconds are too small for attackers to measure over the internet. Statistical timing attacks average thousands of measurements to filter out network jitter — even millisecond differences in HMAC comparison are exploitable remotely.",
    "why_it_matters": "Even microsecond differences in response time can reveal whether a guessed secret is correct, allowing an attacker to recover a password or token character by character.",
    "common_mistakes": [
        "Using === to compare password hashes, HMACs, or tokens — exits early on first byte mismatch.",
        "Using strcmp() which also short-circuits and has additional issues with null bytes.",
        "Not using hash_equals() in PHP for all secret comparisons.",
        "Applying timing-safe comparison only to the final comparison but not to intermediate validation steps."
    ],
    "when_to_use": [
        "Use hash_equals() for all security-sensitive string comparisons — it runs in constant time regardless of where strings differ.",
        "Use password_verify() for password checks — it uses constant-time comparison internally."
    ],
    "avoid_when": [
        "Never use === or == to compare HMAC signatures, API tokens, or password hashes — both short-circuit on the first differing byte.",
        "Do not compare secrets with strcmp() or strncmp() — they are not constant-time."
    ],
    "related": [
        "hash_equals",
        "csrf",
        "predictable_token"
    ],
    "prerequisites": [
        "hash_equals",
        "bcrypt",
        "insecure_randomness"
    ],
    "refs": [
        "https://cwe.mitre.org/data/definitions/208.html",
        "https://www.php.net/manual/en/function.hash-equals.php"
    ],
    "bad_code": "// === exits on first mismatch — reveals partial token via timing\nif (\\$_GET['token'] === \\$secretToken) { grantAccess(); }",
    "good_code": "// hash_equals() — constant-time comparison regardless of where mismatch occurs\nif (hash_equals(\\$secretToken, \\$_GET['token'] ?? '')) {\n    grantAccess();\n}\n\n// For password verification — always use password_verify (also constant-time)\nif (password_verify(\\$input, \\$storedHash)) { /* authenticated */ }\n\n// Timing-safe HMAC comparison for API signatures\n\\$expected = hash_hmac('sha256', \\$requestBody, \\$secret);\n\\$provided = \\$_SERVER['HTTP_X_SIGNATURE'] ?? '';\nif (!hash_equals(\\$expected, \\$provided)) { abort(401); }",
    "quick_fix": "Replace all security-sensitive string comparisons with hash_equals($known, $user_input) — it always takes constant time",
    "severity": "high",
    "effort": "low",
    "created": "2026-03-15",
    "updated": "2026-03-31",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/timing_attack",
        "html_url": "https://codeclaritylab.com/glossary/timing_attack",
        "json_url": "https://codeclaritylab.com/glossary/timing_attack.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 Attack](https://codeclaritylab.com/glossary/timing_attack) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/timing_attack"
            }
        }
    }
}