{
    "slug": "php_variable_variables",
    "term": "Variable Variables ($$var) Risks",
    "category": "security",
    "difficulty": "advanced",
    "short": "$$var creates a variable whose name is the value of $var — using it with user input allows arbitrary variable access/creation and is effectively a backdoor.",
    "long": "$$var is PHP's variable variable syntax: $varName = 'username'; $$varName = 'admin' creates $username = 'admin'. This is almost always a design smell and a security risk when $varName comes from user input. Attackers can read or overwrite any variable in scope. Extract() internally uses the same mechanism. Variable variables are occasionally legitimate (template engines, serialisation) but require a strict whitelist. PHPStan flags them as suspicious. In PHP 7, $$var['key'] was disambiguated: ${$var['key']} vs ${$var}['key'].",
    "aliases": [],
    "tags": [
        "php",
        "security",
        "variable-variables",
        "injection"
    ],
    "misconception": "Variable variables are only a risk if used directly with $_GET — any path where user data influences the variable name (even indirectly) is exploitable.",
    "why_it_matters": "Variable variables give user input control over which program variables are read or written — a path to arbitrary code execution or authentication bypass.",
    "common_mistakes": [
        "Using $$key from a loop over user-supplied array keys.",
        "Not whitelisting allowed variable names before using $$var.",
        "Using variable variables in template code that processes user content."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "php_extract_security",
        "php_register_globals_risk",
        "input_validation"
    ],
    "prerequisites": [
        "input_validation"
    ],
    "refs": [
        "https://www.php.net/manual/en/language.variables.variable.php"
    ],
    "bad_code": "// User sends: field=password&value=attackerPassword\n$field = $_GET['field'];\n$$field = $_GET['value']; // Sets $password = 'attackerPassword'",
    "good_code": "// Whitelist approach:\n$allowed = ['title', 'body', 'author'];\n$field = $_GET['field'] ?? '';\nif (in_array($field, $allowed, true)) {\n    $$field = sanitize($_GET['value'] ?? '');\n}\n\n// Better: explicit mapping\n$data = [\n    'title'  => sanitize($_GET['title'] ?? ''),\n    'body'   => sanitize($_GET['body'] ?? ''),\n];",
    "quick_fix": "Whitelist all variable names before using $$var. Better: replace variable variables with explicit associative arrays. Add phpcs/phpstan rules to flag $$var usage.",
    "severity": "critical",
    "effort": "high",
    "created": "2026-03-22",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/php_variable_variables",
        "html_url": "https://codeclaritylab.com/glossary/php_variable_variables",
        "json_url": "https://codeclaritylab.com/glossary/php_variable_variables.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": "[Variable Variables ($$var) Risks](https://codeclaritylab.com/glossary/php_variable_variables) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/php_variable_variables"
            }
        }
    }
}