{
    "slug": "predictable_token",
    "term": "Predictable Token",
    "category": "security",
    "difficulty": "intermediate",
    "short": "Tokens generated with md5(time()) or rand() are trivially guessable because their entropy source is predictable.",
    "long": "Security tokens (password reset links, session IDs, API keys) must be unpredictable. Using md5(time()) produces only 86,400 distinct values per day — an attacker can brute-force all of them in seconds. rand() and mt_rand() are pseudorandom and their output can be predicted from a small number of observed values. The only correct source for security-sensitive random data is a CSPRNG: bin2hex(random_bytes(32)) in PHP.",
    "aliases": [
        "weak token",
        "guessable token",
        "insecure token generation"
    ],
    "tags": [
        "cryptography",
        "authentication",
        "tokens",
        "cwe-340"
    ],
    "misconception": "Using a hash like md5(time()) produces an unpredictable token. Timestamps have limited entropy — an attacker who knows roughly when a token was generated can brute-force the millisecond-range space in seconds. Use random_bytes(32) instead.",
    "why_it_matters": "Guessable tokens — for sessions, CSRF, password resets, or API keys — allow an attacker to forge or brute-force a valid token without ever authenticating.",
    "common_mistakes": [
        "Using rand() or mt_rand() which are seeded by time and guessable.",
        "Using MD5 or SHA1 of a timestamp — the timestamp is known or estimable.",
        "Sequential integer tokens for anything security-sensitive.",
        "Short tokens (less than 128 bits) that make brute force feasible even with secure randomness."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "random_bytes",
        "weak_cryptography",
        "csprng"
    ],
    "prerequisites": [
        "php_csprng",
        "entropy",
        "weak_session_id"
    ],
    "refs": [
        "https://cwe.mitre.org/data/definitions/338.html",
        "https://www.php.net/manual/en/function.random-bytes.php"
    ],
    "bad_code": "// Predictable — attacker can guess or brute-force\n\\$token = md5(\\$userId . time());\n\\$token = uniqid();   // only 7 bytes of entropy\n\\$token = rand();     // seeded from time — predictable",
    "good_code": "// 32 bytes = 256 bits of entropy — computationally unguessable\n\\$token = bin2hex(random_bytes(32)); // 64 hex chars\n\n// Store hash in DB, send raw token to user\n\\$stored = hash('sha256', \\$token);\n\\$db->insert('password_resets', [\n    'user_id'    => \\$userId,\n    'token_hash' => \\$stored,\n    'expires_at' => date('Y-m-d H:i:s', time() + 3600),\n]);\n\n// Verify with constant-time comparison:\nif (!hash_equals(\\$stored, hash('sha256', \\$inputToken))) abort(400);\nif (\\$record->expires_at < now()) abort(400);",
    "quick_fix": "Use bin2hex(random_bytes(32)) for all tokens — password reset, email verification, API keys, CSRF; the 256-bit entropy makes brute force infeasible",
    "severity": "critical",
    "effort": "low",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/predictable_token",
        "html_url": "https://codeclaritylab.com/glossary/predictable_token",
        "json_url": "https://codeclaritylab.com/glossary/predictable_token.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": "[Predictable Token](https://codeclaritylab.com/glossary/predictable_token) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/predictable_token"
            }
        }
    }
}