{
    "slug": "insecure_deserialization",
    "term": "Insecure Deserialization",
    "category": "security",
    "difficulty": "advanced",
    "short": "Untrusted data passed to unserialize() can trigger PHP magic methods and lead to remote code execution.",
    "long": "PHP's unserialize() reconstructs objects from a serialised string, invoking magic methods like __wakeup() and __destruct() in the process. Attackers can craft serialised payloads that exploit available classes (known as \"gadget chains\") to achieve arbitrary code execution, file deletion, or privilege escalation — without needing a file upload. The safe alternative is json_decode() for data exchange; if serialisation is required, restrict allowed_classes.",
    "aliases": [
        "unsafe deserialization",
        "unserialize attack",
        "PHP object injection"
    ],
    "tags": [
        "injection",
        "rce",
        "owasp-top10",
        "cwe-502"
    ],
    "misconception": "Validating data before unserializing it makes the operation safe. PHP's unserialize() instantiates objects and triggers magic methods (__wakeup, __destruct) during deserialization itself — the damage happens before your validation code runs.",
    "why_it_matters": "PHP's unserialize() triggers __wakeup and __destruct magic methods on attacker-controlled objects — chained together, existing classes can be weaponised into remote code execution without any custom exploit code.",
    "common_mistakes": [
        "Passing user-supplied cookies, tokens, or POST data directly to unserialize().",
        "Believing that a HMAC on the serialized string is sufficient — if the verification is bypassable, it isn't.",
        "Not using json_decode() or other format-specific parsers when PHP object serialization is not needed.",
        "Using unserialize() with allowed_classes but not restricting the class list tightly enough."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "json_decode"
    ],
    "prerequisites": [
        "php_object_injection",
        "insecure_randomness"
    ],
    "refs": [
        "https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection",
        "https://cwe.mitre.org/data/definitions/502.html"
    ],
    "bad_code": "// Deserialising untrusted data — attacker crafts a payload\n// that triggers arbitrary PHP object instantiation\n$data = unserialize($_COOKIE['session']);\n// Any class with __wakeup() or __destruct() in scope\n// can be chained into a POP chain for RCE",
    "good_code": "// Never unserialize untrusted input — use JSON instead\n$data = json_decode(base64_decode($_COOKIE['session']), true);\n\n// If you must use serialization, whitelist allowed classes:\n$data = unserialize($input, ['allowed_classes' => [SafeValueObject::class]]);\n\n// Best: sign the payload so tampering is detected\n$payload = base64_encode(json_encode($data));\n$sig     = hash_hmac('sha256', $payload, $_ENV['SECRET']);\n$cookie  = $payload . '.' . $sig;\n\n// Verify on read:\n[$payload, $sig] = explode('.', $cookie, 2);\nif (!hash_equals(hash_hmac('sha256', $payload, $_ENV['SECRET']), $sig)) abort(400);\n$data = json_decode(base64_decode($payload), true);",
    "quick_fix": "Replace unserialize() with json_decode(); if unavoidable use allowed_classes:false and HMAC-sign the serialised payload",
    "severity": "critical",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/insecure_deserialization",
        "html_url": "https://codeclaritylab.com/glossary/insecure_deserialization",
        "json_url": "https://codeclaritylab.com/glossary/insecure_deserialization.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": "[Insecure Deserialization](https://codeclaritylab.com/glossary/insecure_deserialization) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/insecure_deserialization"
            }
        }
    }
}