此文章为XIUNOX版本重构审计时发现问题,XIUNOX版本已优化修复此问题。分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 在框架引导阶段与参数过滤阶段直接调用 get_magic_quotes_gpc() 和 get_magic_quotes_runtime()。这两个函数在 PHP 5.4 起恒返回 FALSE,PHP 7.4 进入废弃,PHP 8.0 起整体移除 。PHP 8 下调用会抛出 Fatal error: Uncaught Error: Call to undefined function get_magic_quotes_gpc(),导致框架在每次请求初始化时即崩溃。
源码证据
文件 xiunobbs_4.0.4/xiunophp/xiunophp.php(DEBUG > 1 时加载的源码版框架):
php
// 第 20 行:框架启动阶段,无任何 function_exists 保护,PHP 8 直接 Fatal error
$get_magic_quotes_gpc = get_magic_quotes_gpc();
// 第 112 行:将结果存入 $_SERVER,供后续 param_force 使用
$_SERVER['get_magic_quotes_gpc'] = $get_magic_quotes_gpc;
文件 xiunobbs_4.0.4/xiunophp/xiunophp.min.php(生产模式默认加载,第 20、110 行同上逻辑):
php
// 第 20 行
$get_magic_quotes_gpc = get_magic_quotes_gpc();
// 第 110 行
$_SERVER['get_magic_quotes_gpc'] = $get_magic_quotes_gpc;
文件 xiunobbs_4.0.4/xiunophp/misc.func.php:
php
// 第 132 行:param_force() 中通过 _SERVER 读取之前缓存的值
function param_force($val, $defval, $htmlspecialchars = TRUE, $addslashes = FALSE) {
$get_magic_quotes_gpc = _SERVER('get_magic_quotes_gpc');
...
// 第 142-143 行:依赖 $get_magic_quotes_gpc 决定是否 addslashes/stripslashes
$addslashes AND !$get_magic_quotes_gpc && $v = addslashes($v);
!$addslashes AND $get_magic_quotes_gpc && $v = stripslashes($v);
...
// 第 159-160 行:同上
$addslashes AND !$get_magic_quotes_gpc && $val = addslashes($val);
!$addslashes AND $get_magic_quotes_gpc && $val = stripslashes($val);
文件 xiunobbs_4.0.4/xiunophp/xn_send_mail.func.php:
php
// 第 1640 行:EncodeFile() 中直接调用 get_magic_quotes_runtime(),无 function_exists 保护
$magic_quotes = get_magic_quotes_runtime();
if ($magic_quotes) {
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
set_magic_quotes_runtime(0);
} else {
ini_set('magic_quotes_runtime', 0);
}
}
注:xn_send_mail.func.php 第 1635-1638 行虽尝试用 function_exists('get_magic_quotes') 定义一个本地替代函数,但函数名拼写为 get_magic_quotes(既非 get_magic_quotes_gpc 也非 get_magic_quotes_runtime),实际无法拦截第 1640 行对 get_magic_quotes_runtime 的调用:
php
if (function_exists('get_magic_quotes')) {
function get_magic_quotes() {
return false;
}
}
$magic_quotes = get_magic_quotes_runtime(); // 仍然调用真实函数,PHP 8 Fatal error
风险等级与结论
兼容障碍(致命) 。get_magic_quotes_gpc 与 get_magic_quotes_runtime 在 PHP 8.0 被移除,调用即 Fatal error: Call to undefined function。
危害:
xiunophp.php第 20 行 /xiunophp.min.php第 20 行:框架每次启动即崩溃,整个站点 502/白屏。xn_send_mail.func.php第 1640 行:发送带附件邮件时调用EncodeFile(),PHP 8 下 Fatal error,邮件功能完全不可用。param_force()依赖缓存的$_SERVER['get_magic_quotes_gpc'],由于框架启动阶段已 Fatal,无法到达此处;即便人工绕过启动,$get_magic_quotes_gpc永远为 NULL,会触发stripslashes误剥合法反斜杠。
修复建议:
xiunophp.php第 20 行 /xiunophp.min.php第 20 行:删除$get_magic_quotes_gpc = get_magic_quotes_gpc();,直接$get_magic_quotes_gpc = FALSE;;或用function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()兼容写法。xn_send_mail.func.php第 1640 行:改为$magic_quotes = function_exists('get_magic_quotes_runtime') ? get_magic_quotes_runtime() : false;。- 第 1635-1638 行的
get_magic_quotes替代函数命名错误且无意义,建议直接删除整段 if 块。 - 同步移除第 1643、1652 行的
set_magic_quotes_runtime()调用(详见独立报告)。