{
    "slug": "prototype_pollution",
    "term": "Prototype Pollution",
    "category": "security",
    "difficulty": "advanced",
    "short": "An attacker injects properties into JavaScript's Object.prototype, affecting all objects in the application.",
    "long": "Prototype pollution is a JavaScript-specific vulnerability where user-controlled keys like __proto__ or constructor.prototype are used to write properties onto Object.prototype. Because all JavaScript objects inherit from Object.prototype, injected properties propagate globally and can override application logic, bypass security checks, or escalate to remote code execution in server-side Node.js contexts. PHP is not affected, but PHP applications serving JavaScript-heavy frontends should sanitise JSON inputs and use libraries with known mitigations.",
    "aliases": [
        "JS prototype pollution",
        "__proto__ attack",
        "object prototype injection"
    ],
    "tags": [
        "javascript",
        "injection",
        "nodejs",
        "cwe-1321"
    ],
    "misconception": "Prototype pollution is only exploitable in the browser. Server-side JavaScript (Node.js) is equally vulnerable — polluting Object.prototype can affect all objects in the process, enabling DoS, property injection, and in some cases RCE via gadget chains.",
    "why_it_matters": "Polluting JavaScript's Object.prototype affects every object in the runtime — attackers can inject properties that alter application behaviour, bypass checks, or enable XSS.",
    "common_mistakes": [
        "Deep-merging objects using recursive assignment without checking for __proto__ or constructor keys.",
        "Using user-supplied strings as keys in object assignment — an attacker sends __proto__[isAdmin]=true.",
        "Not using Object.create(null) for dictionaries/maps that accept user-controlled keys.",
        "Ignoring prototype pollution in server-side Node.js — it's not only a browser problem."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "xss",
        "insecure_deserialization"
    ],
    "prerequisites": [
        "js_closures",
        "js_prototype",
        "input_validation"
    ],
    "refs": [
        "https://portswigger.net/web-security/prototype-pollution",
        "https://cheatsheetseries.owasp.org/cheatsheets/Prototype_Pollution_Prevention_Cheat_Sheet.html"
    ],
    "bad_code": "// JavaScript — merging user object pollutes Object.prototype\nfunction merge(target, source) {\n    for (let key in source) {\n        target[key] = source[key]; // key could be '__proto__'\n    }\n}\nmerge({}, JSON.parse('{\"__proto__\":{\"admin\":true}}'));\nconsole.log({}.admin); // true — every new object is now 'admin'",
    "good_code": "// Use Object.keys() — own keys only, no prototype chain\nfunction safeMerge(target, source) {\n    for (let key of Object.keys(source)) {\n        if (['__proto__','constructor','prototype'].includes(key)) continue;\n        target[key] = source[key];\n    }\n}\n\n// Or use Object.create(null) — no prototype at all\nconst safe = Object.create(null);\n\n// Or JSON round-trip for deep clone of untrusted data:\nconst clone = JSON.parse(JSON.stringify(untrusted));\n\n// PHP note: not applicable — PHP objects don't share a mutable prototype",
    "quick_fix": "Never merge user-supplied objects into application objects with recursive merge; use Object.create(null) for hash maps; validate that __proto__ and constructor keys are absent",
    "severity": "high",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/prototype_pollution",
        "html_url": "https://codeclaritylab.com/glossary/prototype_pollution",
        "json_url": "https://codeclaritylab.com/glossary/prototype_pollution.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": "[Prototype Pollution](https://codeclaritylab.com/glossary/prototype_pollution) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/prototype_pollution"
            }
        }
    }
}