Vulnerability code (user permission check):
$is_admin = false; extract($_GET); // No overwrite protection if ($is_admin) { show_admin_dashboard(); }
Attack Principle:
Exploit Example:
http://target.com/admin.php?is_admin=1
Fixes:
// Prevent overwriting existing variables extract($_GET, EXTR_SKIP); // Or prefix user variables extract($_GET, EXTR_PREFIX_ALL, 'user');
Vulnerability code (configuration update function):
$config = ['debug' => false]; parse_str(file_get_contents('php://input'), $input); foreach ($input as $key => $value) { $config[$key] = $value; // Configuration overwrite }
Attack Principle:
Payload Example:
POST /update_config.php Content-Type: application/x-www-form-urlencoded debug=1&admin=1
Fix:
$allowed_keys = ['theme', 'language']; foreach ($input as $key => $value) { if (in_array($key, $allowed_keys)) { $config[$key] = $value; } }
Vulnerable Code:
foreach ($_REQUEST as $key => $value) { $$key = htmlspecialchars($value); // Dangerous! } if ($is_admin) { grant_privileges(); }
Attack Principle:
Fix:
$allowed = ['username', 'email']; foreach ($_REQUEST as $key => $value) { if (in_array($key, $allowed)) { $$key = htmlspecialchars($value); } }
Vulnerable Code (Old PHP < 5.4.0):
import_request_variables('GPC'); // Registers GET/POST/Cookie as variables if ($_SESSION['is_admin']) { show_admin_menu(); }
Attack principle:
Attack:
Submit is_admin=1 via Cookie to create the variable.
Payload Example:
GET /admin.php HTTP/1.1 Cookie: is_admin=1
Fix:
Vulnerability code (multi-layer variable processing):
$a = 'original'; $b = 'a'; $c = 'b'; $$$$c = 'hacked'; // Equivalent to $a = 'hacked'; echo $a;
Attack scenario:
Fix:
$allowed_vars = ['user', 'page']; if (!in_array($var_name, $allowed_vars)) { die('Illegal variable name'); }
Vulnerability code (IP whitelist verification):
$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR']; $allow_ips = ['192.168.1.0/24']; if (in_array($client_ip, $allow_ips)) { show_sensitive_data(); }
Attack principle:
Fix:
$client_ip = $_SERVER['REMOTE_ADDR']; if (!ip_in_range($client_ip, $allow_ips)) { die("Unauthorized access"); }
Vulnerable Code:
$input = '%82%A0%82%A2=admin'; // Shift_JIS encoded mb_parse_str($input, $params); if ($params['admin'] ?? false) { enable_admin(); }
Attack principle:
Exploitation:
http://target.com/?%82%A0%82%A2=1
Fix:
mb_internal_encoding('UTF-8'); parse_str(htmlspecialchars_decode($input), $params);
Vulnerable code (cache system):
class Cache { public $storage; public function __wakeup() { foreach ($this->storage as $k => $v) { $$k = $v; } } } $data = unserialize($_COOKIE['cache']);
Attack principle:
Exploit Payload:
$exploit = new Cache(); $exploit->storage = ['is_admin' => true]; setcookie('cache', serialize($exploit));
Fix:
class Cache { public function __wakeup() { foreach ($this->storage as $k => $v) { $_SESSION[$k] = $v; } } }
Vulnerability code (custom route parsing):
preg_match('/\/user\/(?<id>\d+)/', $_SERVER['PATH_INFO'], $matches); extract($matches); // Overwrites $id
Attack principle:
Exploit:
http://target.com/user/123?id=0xHACKED
Fix:
if (!preg_match('/^\/user\/\d+$/', $_SERVER['PATH_INFO'])) { die("Illegal route"); }
Vulnerability code (LDAP authentication module):
$ldap_query = "(&(cn=$username)(userPassword=$password))"; ldap_set_option($link, LDAP_OPT_DEREF, $_GET['deref']); $_ENV['LDAP_HOST'] = 'ldap://hacker.com';
Attack principle:
Fix:
$deref = in_array($_GET['deref'], [0,1,2,3]) ? (int)$_GET['deref'] : 0; ldap_set_option($link, LDAP_OPT_DEREF, $deref);
rules: - id: variable-override patterns: - pattern: extract($_, ...) - pattern: parse_str(..., $_) - pattern: $$var = ... message: "Potential variable overwrite vulnerability"
payloads = [ 'GLOBALS[admin]=1', '_SESSION[user]=admin', 'HTTP_X_OVERRIDE=1', '1=1&_method=PUT' # Framework parameter override ]
function track_variable_changes($name, $value) { if (in_array($name, ['is_admin', 'config'])) { log_security_event("Sensitive variable modified: $name = $value"); } }
Attack chain structure :
Vulnerable Chain:
parse_str(file_get_contents('php://input'), $new_config); $config = array_merge($config, $new_config);
Malicious Input:
config[upload_dir]=/var/www/html/images&config[disable_functions]=
Audit focus$$ : Globally search for keywords such as , extract(, parse_str(, etc. in the code mb_parse_str(, paying special attention to scenarios with secondary dynamic assignment (such as $var = $$dynamic_var).
+---------------------------+-------------------------------------------------------+-------------------------+ | Dangerous Mode | Code Pattern | Detection Focus | +---------------------------+-------------------------------------------------------+-----------------------------------------------+ | Unprotected extract() | extract($_POST) | Check second parameter (e.g., EXTR_SKIP) | | Dynamic parse_str() | parse_str($input) | Is input controllable? | | Variable variable $$var | foreach ($_GET as $k => $v) { $$k = $v; } | Loop variable logic | | Global Registration | register_globals = On | php.ini configuration | | Variable name concat | $var = ${"prefix_" . $_GET['field']}; | Is user input defining variable names? | +---------------------------+-------------------------------------------------------+-------------------------+
Scenario: Implement file inclusion by overriding configuration
Vulnerable Code:
$config_file = 'default.cfg'; extract($_GET); include($config_file . '.php');
Attack steps :
Exploit:
?config_file=../../etc/passwd%00
Fix:
$allowed_files = ['default.cfg', 'user.cfg']; if (!in_array($config_file, $allowed_files)) { die("Invalid configuration file."); }
// Filter special characters $clean = array(); $input = preg_replace('/[^a-z0-9_]/i', '', $_GET['param']);
; php.ini disable_functions = extract, parse_str, import_request_variables
// Explicit assignment instead of extract() $username = $_POST['username'] ?? ''; $email = $_POST['email'] ?? '';
Through the above cases and analysis, you should be able to:
Practical advice : When auditing code, focus on code areas that process user input, especially logic modules that involve dynamic variable creation and global parameter processing. Use grepthe command to search for key functions:
grep -rn --include=*.php "extract(" /path/to/code grep -rn --include=*.php "\$\$" /path/to/code