PHP 7.2变量覆盖漏洞仍存,主因是extract()、parse_str()、可变变量及不安全循环赋值;防护核心是切断用户输入到变量名/值的直接映射,需禁用危险函数、强制白名单、显式取值、初始化变量、严格类型与封装控制。

PHP 7.2 虽已移除 register_globals,但变量覆盖漏洞依然存在,主要来自 extract()、parse_str()、可变变量($$)及不安全的循环赋值逻辑。防护核心是:**切断用户输入到变量名/值的直接映射链路**,不依赖配置,而靠代码层主动约束。
禁用或严控 extract() 函数
extract() 是 PHP 7.2 中最常见、最危险的覆盖入口。默认 EXTR_OVERWRITE 模式允许攻击者通过请求参数覆盖 $is_login、$admin_level 等关键变量。
- 彻底删除无白名单的调用,如
extract($_GET)或extract($_REQUEST) - 必须使用时,强制指定过滤模式和键名白名单:
extract($_POST, EXTR_IF_EXISTS, ['page', 'limit', 'sort']) - 更推荐替代方案:显式取值,例如
$page = $_POST['page'] ?? 1;,配合类型校验(如filter_var($page, FILTER_VALIDATE_INT))
规范 parse_str() 和 mb_parse_str() 使用
这两个函数若未指定目标数组,会将解析结果写入当前作用域,造成隐式变量覆盖。
- 禁止写法:
parse_str($_GET['data']);(无第二个参数) - 必须写成:
$output = []; parse_str($_GET['data'], $output);,后续只从$output中读取 - 对
$output再做一次白名单过滤,避免传入恶意键名(如__destruct)
杜绝可变变量与未初始化变量风险
可变变量 $$key 和未声明就使用的变量(如 foreach($_POST as $k=>$v) { $data[$k] = $v; })极易被利用。
立即学习“PHP免费学习笔记(深入)”;
- 检查所有
$$用法,确保$key来自预设常量或严格校验后的值,禁止直接来自$_GET或$_POST - 关键变量必须提前初始化:
$where = '';、$config = [];,避免被后续extract或循环覆盖 - 批量赋值不用
foreach直接映射,改用白名单交集:$allowed = array_intersect_key($_POST, array_flip(['name', 'email', 'status']));
强化类型与作用域控制(PHP 7.2 特性)
利用 PHP 7.2 已支持的严格类型和属性可见性,从语言机制上收窄覆盖面。
- 在文件顶部添加
declare(strict_types=1);,让函数参数校验更刚性,减少因类型转换引发的逻辑绕过 - 类中敏感状态用
private或protected属性封装,禁止外部直接写入:private bool $is_admin = false; - 对外提供受控 setter 方法,在赋值前校验来源和格式,例如:
public function setToken(string $t): void { if (strlen($t) === 32 && ctype_xdigit($t)) $this->token = $t; }



















