Xiuno BBS 审计之问题16:get_magic_quotes在 PHP 8.0 被移除

此文章为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_gpcget_magic_quotes_runtime 在 PHP 8.0 被移除,调用即 Fatal error: Call to undefined function

危害:

  1. xiunophp.php 第 20 行 / xiunophp.min.php 第 20 行:框架每次启动即崩溃,整个站点 502/白屏。
  2. xn_send_mail.func.php 第 1640 行:发送带附件邮件时调用 EncodeFile(),PHP 8 下 Fatal error,邮件功能完全不可用。
  3. param_force() 依赖缓存的 $_SERVER['get_magic_quotes_gpc'],由于框架启动阶段已 Fatal,无法到达此处;即便人工绕过启动,$get_magic_quotes_gpc 永远为 NULL,会触发 stripslashes 误剥合法反斜杠。

修复建议:

  1. 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() 兼容写法。
  2. xn_send_mail.func.php 第 1640 行:改为 $magic_quotes = function_exists('get_magic_quotes_runtime') ? get_magic_quotes_runtime() : false;
  3. 第 1635-1638 行的 get_magic_quotes 替代函数命名错误且无意义,建议直接删除整段 if 块。
  4. 同步移除第 1643、1652 行的 set_magic_quotes_runtime() 调用(详见独立报告)。
相关推荐
码事漫谈1 小时前
类型即世界:一个 C++ 程序员的本体论入门
后端
Rain的Java大神之路1 小时前
JavaWeb开发如何解决跨域问题
java·前端·后端·nginx·web安全·面试·运维开发
IT_陈寒3 小时前
Python的多线程居然是个假把式?搞清GIL让我少熬三天夜
前端·人工智能·后端
明月_清风3 小时前
位图与布隆过滤器:海量数据下的"存在性判断"艺术
前端·后端·算法
明月_清风4 小时前
Hash 表从入门到精通:Go 实战与工程细节
前端·后端·算法
考虑考虑4 小时前
ElasticSearch索引命令
运维·后端·elasticsearch
玉宇夕落5 小时前
背单词项目一:融会贯通:从零构建"单词大师"后台——Next.js + Supabase + Drizzle 全栈开发实战
后端
橙序员小站5 小时前
从 Demo 到生产:Agent Harness 如何把 AI 真正“接”进项目
后端·aigc·ai编程
她的男孩5 小时前
一个开源低代码框架的协作 SPI 是怎么设计的 ForgeAdmin 拆解 + 实战接入新平台
后端·算法·架构
蓝山6166 小时前
Python 字典(Dictionary)完全指南:从入门到实战
后端