PHP7和PHP5在安全上的区别
字数 1622 2025-08-18 11:38:08
PHP7与PHP5安全特性对比分析
前言
PHP7相比PHP5在安全性方面做出了多项重要改进,这些改动直接影响了许多传统Web渗透技术和后门利用方式。本文详细分析PHP7与PHP5在安全方面的主要区别,帮助开发者和安全研究人员了解这些变化。
函数修改
1. preg_replace()不再支持/e修饰符
PHP5情况:
preg_replace("/.*/e", $_GET["h"], "");
/e修饰符允许将替换后的字符串作为PHP代码执行(eval方式)。
PHP7变化:
- 完全移除了/e修饰符支持
- 替代方案:使用
preg_replace_callback()
PHP7替代实现:
preg_replace_callback("/.*/", function ($a){ @eval($a[0]); }, $_GET["h"]);
2. create_function()被废弃
PHP5后门示例:
$func = create_function('', $_POST['cmd']);
$func();
PHP7影响:
- 该函数内部使用eval实现,移除后少了一种后门创建方式
- 可使用匿名函数直接替代
3. mysql_*系列函数移除
变化内容:
- 移除了
mysql_connect()、mysql_query()等传统MySQL函数 - 官方推荐使用mysqli或PDO_MySQL
安全影响:
- 推动开发者使用参数化查询,减少SQL注入风险
- 但需注意:预编译查询的正确使用才是关键
4. unserialize()增加白名单参数
新函数签名:
unserialize($serializedObj, ["allowed_classes" => true|false|array]);
选项说明:
true:允许所有类(默认,向后兼容)false:将所有对象转换为__PHP_Incomplete_Class对象- 数组:类名白名单
安全影响:
- 提供了防御不安全反序列化的机制
- 但目前仍是可选参数,不是强制要求
5. assert()默认不再执行代码
PHP5情况:
assert('eval($_POST[cmd])'); // 可执行代码
PHP7变化:
- assert()现在仅用于断言检查,不再执行代码
- 导致大量基于assert()的Webshell失效
影响范围:
- 中国菜刀等工具使用的assert()函数失效
- 通常需要修改为eval()才能正常工作
语法修改
1. foreach不再改变内部数组指针
PHP5行为:
$a = array('1','2','3');
foreach ($a as $k=>&$n){ echo ""; }
foreach ($a as $k=>$n){ echo ""; } // 会影响数组值
PHP7变化:
- 通过值遍历时操作数组副本,不影响原数组
- 注:仅影响PHP7.0.0版本,后续版本恢复原行为
2. 8进制字符容错率降低
PHP5行为:
octdec('012999999999999') == octdec('012'); // true
无效8进制数字被静默截断
PHP7变化:
- 无效8进制数字会触发解析错误
- 注:仅影响PHP7.0.0版本,后续版本恢复原行为
3. 十六进制字符串不再被认为是数字
PHP5行为:
var_dump("0x123" == "291"); // true
var_dump(is_numeric("0x123")); // true
PHP7变化:
- 严格区分十六进制字符串和数字
- 此修改是永久性的,未在后续版本恢复
安全影响:
- 影响某些CTF解题技巧
- 减少类型混淆漏洞利用可能性
4. 移除了ASP和script PHP标签
移除的标签形式:
<% %>
<script language="php"> </script>
保留的标签:
<?php ?>
其他安全相关修改
1. 超大浮点数类型转换
PHP5行为:
- 超大浮点数转整数时静默截断
PHP7行为:
- 会报错,防止不可预期的截断行为
2. 执行函数对NULL增加保护
涉及函数:
exec(),system(),passthru()- 对NULL输入增加了安全处理
3. parse_str()必须使用第二个参数
PHP5行为:
parse_str("a=1&b=2"); // 变量$a和$b被创建
PHP7要求:
parse_str("a=1&b=2", $output); // 必须提供输出变量
安全影响:
- 防止意外污染当前符号表
- 减少变量注入风险
4. 杂项修改
list()不再能解开字符串变量$HTTP_RAW_POST_DATA被移除__autoload()方法被废弃- 统一了不同平台下的整型长度
session_start()可接受配置数组覆盖php.ini设置
总结
PHP7的这些安全改进总体上提高了语言的安全性,使得许多传统的Web攻击技术失效。主要影响包括:
- Webshell技术需要更新,许多传统后门函数被移除或限制
- 数据类型处理更加严格,减少类型混淆漏洞
- 推动更安全的编程实践,如参数化查询
- 提供了更多安全控制选项,如反序列化白名单
开发者应当了解这些变化,及时更新代码;安全研究人员也需要调整测试方法,适应PHP7的新特性。