Xiuno BBS 审计之问题1:mysql_* 扩展移除,PHP8 致命错误此文章为XIUNOX版本重构审计时发现问题,XIUNOX版本已优化修复此问题。分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 的 db_mysql 数据库驱动类以及安装向导大量调用 mysql_connect / mysql_query / mysql_fetch_assoc / mysql_select_db / mysql_error / mysql_errno / mysql_insert_id / mysql_affected_rows / mysql_close 等 ext/mysql 系列函数。该扩展在 PHP 5.5 被废弃,PHP 7.0 起整体移除,在 PHP 8 上调用会直接抛出 Fatal error: Uncaught Error: Call to undefined function mysql_connect(),导致数据库连接、查询、安装全部不可用。
源码证据
文件 xiunobbs_4.0.4/xiunophp/db_mysql.class.php(核心 mysql 驱动,共 13 处真实调用):
// 第 53-55 行:连接与选库 $link = @mysql_connect($host, $user, $password); // 如果用户名相同,则返回同一个连接。 fastcgi 持久连接更省资源 if(!$link) { $this->error(mysql_errno(), '连接数据库服务器失败:'.mysql_error()); return FALSE; } if(!mysql_select_db($name, $link)) { $this->error(mysql_errno(), '选择数据库失败:'.mysql_error()); return FALSE; } // 第 64, 77 行:结果集获取 $r = mysql_fetch_assoc($query); while($arr = mysql_fetch_assoc($query)) { // 第 106, 131 行:执行 SQL $query = mysql_query($sql, $link); $query = mysql_query($sql, $this->wlink); // 第 138, 140 行:获取 INSERT/UPDATE 影响 return mysql_insert_id($this->wlink); return mysql_affected_rows($this->wlink); // 第 175, 177 行:关闭连接 $r = mysql_close($this->wlink); $r = mysql_close($this->rlink); // 第 188-189 行:错误信息 $this->errno = $errno ? $errno : ($this->link ? mysql_errno($this->link) : mysql_errno()); $this->errstr = $errstr ? $errstr : ($this->link ? mysql_error($this->link) : mysql_error());
文件 xiunobbs_4.0.4/xiunophp/xiunophp.min.php(第 39 行整行压制的 db_mysql 类,逻辑与上面一致,包含相同的 13 处 mysql_* 调用,作为生产模式默认加载文件)。
文件 xiunobbs_4.0.4/install/index.php:
// 第 81 行:安装向导用 function_exists 探测 mysql_connect,PHP 8 下永远返回 FALSE,导致安装界面提示“不支持 mysql” $mysql_support = function_exists('mysql_connect'); // 第 135 行:当 $type == 'mysql' 时直接调用 mysql_query 建库,PHP 8 下 Fatal error if($type == 'mysql') { mysql_query("CREATE DATABASE $name"); $r = db_connect($db); }
文件 xiunobbs_4.0.4/xiunophp/db.func.php 第 71-74 行:注释中提及 mysql_insert_id/mysql_affected_rows/mysql_exec,虽非真实调用,但说明设计期仍假定 mysql 驱动存在。
统计:真实 mysql_* 函数调用 —— db_mysql.class.php 13 处、xiunophp.min.php 13 处(同逻辑压缩)、install/index.php 2 处(function_exists('mysql_connect') 探测 1 处 + mysql_query 1 处)。
风险等级与结论
兼容障碍(致命)。ext/mysql 在 PHP 7.0 已被整体移除,PHP 8 中调用任意 mysql_* 函数均触发 Fatal error: Call to undefined function。
危害:
- 当
conf['db']['type'] == 'mysql'时(conf.default.php默认值即'mysql'),站点启动即崩溃,无法连接数据库。 - 安装向导第 81 行
function_exists('mysql_connect')永远返回 FALSE,若用户未启用 PDO,会被错误提示“环境不支持”而无法继续;若选type=mysql,第 135 行建库直接 Fatal error。 xiunophp.min.php是DEBUG <= 1时的默认加载文件,影响所有生产环境。
修复建议:
- 强制将默认
db.type改为pdo_mysql,从conf.default.php、conf/conf.php、安装向导中移除mysql类型选项;或在db_new()中拒绝'mysql'类型并回退到pdo_mysql。 - 删除
xiunophp/db_mysql.class.php与xiunophp.min.php中的class db_mysql,统一使用db_pdo_mysql。 install/index.php第 81 行改为只检测pdo_mysql,第 134-136 行的mysql_query("CREATE DATABASE $name")改为通过 PDO 执行CREATE DATABASE。- 若必须保留
db_mysql类以兼容老配置,应在db_mysql.class.php顶部if(!function_exists('mysql_connect')) return;并在db_new()中提示用户切换驱动。