php7.3中extract()仍存在变量覆盖风险,因未校验外部输入而直接注册键名为变量;高危调用包括extract($_get)等三类;修复应禁用该函数、改用显式赋值或白名单提取。

extract()在PHP7.3中仍存在变量覆盖风险
PHP7.3并未移除或默认限制extract()函数的行为,它依然会将$_GET等数组的键名直接注册为变量,并在同名时无条件覆盖已有变量。该行为未因PHP版本升级而改变,漏洞本质仍是“未经校验地导入外部输入”,而非语法兼容性问题。
关键检测点:三类高危调用模式
审计代码时,重点检查以下写法(尤其出现在逻辑分支前、敏感判断附近):
-
extract($_GET)、extract($_REQUEST)、extract($_POST)—— 最常见且最危险,完全开放用户控制变量名 -
extract($user_input),其中$user_input来自file_get_contents('php://input')、JSON解码结果或数据库读取 —— 输入源隐蔽,易被忽略 - 虽指定
EXTR_PREFIX_SAME等规则,但未排除关键变量(如$flag、$auth、$is_admin),仍可能绕过逻辑校验
推荐修复方式:禁用 + 替代 + 白名单
不依赖“加个参数就安全”,需分层加固:
-
首选方案:彻底弃用
extract(),改用显式赋值。例如:$name = $_GET['name'] ?? '';或使用filter_input()做类型和合法性校验 -
若必须保留(如遗留系统),强制使用
EXTR_SKIP并限定作用域:extract($_GET, EXTR_SKIP);—— 此时已有变量不会被覆盖,但需确保所有预期变量都已提前声明并初始化 -
白名单提取:仅允许特定键名进入符号表,例如:
$allowed = ['id', 'page', 'sort']; extract(array_intersect_key($_GET, array_flip($allowed)), EXTR_SKIP);
辅助防御:运行时拦截与日志监控
在入口文件或中间件中可加入轻量级防护逻辑:
- 对
$_GET中疑似危险键名(如flag、GLOBALS、_SESSION、phpinfo)记录告警日志 - 使用
get_defined_vars()对比extract()前后变量数量/键名变化,发现异常新增变量时触发调试钩子(仅限开发环境) - 配合SAST工具(如PHPStan+自定义规则)静态扫描
extract(调用,标记上下文是否含敏感变量操作
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











