CWE-627, Dynamic Variable Evaluation, applies in languages where a user can influence a variable name at runtime. MITRE lists PHP and Perl. If names are not controlled, an attacker can read or write arbitrary variables or access arbitrary functions.
How it happens
PHP's variable variables and dynamic function calls resolve a name from a string. When that string comes from a request, the request chooses what gets touched.
// Vulnerable: the request picks the variable and the function
$field = $_GET['field'];
echo $$field; // ?field=_SERVER or a secret variable
$fn = $_GET['action'];
$fn($_GET['arg']); // calls any function by name
The effect depends on what is reachable from the crossover point. MITRE's observed cases are chains: dynamic variable evaluation enabling remote file inclusion and path traversal (CVE-2009-0422), modification of an unexpected $_SERVER variable leading to XSS, and a mail program that let one user read and modify another's attachments and preferences.
What an attacker gains
Confidentiality, integrity and availability are all listed. An attacker can gain unauthorized access to internal program variables and execute arbitrary code.
How to find it
The record lists no detection methods. Search for variable variables ($$), call_user_func, and any call whose function name comes from input, then trace where the string originates.
How to fix it
From MITRE:
- Refactor to avoid dynamic variable evaluation whenever possible.
- Use only allowlists of acceptable variable or function names.
- For function names, call only functions that accept the proper number of arguments, to avoid unexpected null arguments.
$allowed = ['view' => 'show_view', 'list' => 'show_list'];
$action = $_GET['action'] ?? '';
if (isset($allowed[$action])) { $allowed[$action](); }
A closer look at the chain effect
Dynamic variable evaluation rarely appears alone. MITRE's examples are mostly chains: the dynamic lookup gives the attacker control of a variable, and that variable feeds a second weakness such as remote file inclusion, path traversal or cross-site scripting.
This is worth knowing during triage. A report that says only "user controls a variable name" can look minor. Follow the data. Where does the variable go next? A path, a function call or a header makes the finding serious.
One example in the record changed a critical, unexpected $_SERVER variable. Application authors tend to trust superglobals, so an overwrite there bypasses assumptions elsewhere in the code.
The simplest defense is a lookup table. Map the strings you accept to the functions or fields you intend to expose, and refuse everything else. The table also doubles as documentation of what the endpoint can do.
Review checklist:
- Search for variable variables and calls where the function name is a variable.
- Trace each name back to its source and mark the ones that come from a request.
- Replace them with a lookup table of permitted names.
- Test with names you did not intend to allow, such as superglobal names, and confirm they are refused.
Repeat the review when new endpoints are added, since the pattern tends to return through convenience code.
Quick check
Why is an allowlist better than filtering?
An allowlist names exactly what is permitted, so unexpected names are rejected by default. Filtering has to guess every dangerous name.