Xiuno BBS 审计之问题1:mysql_* 扩展移除,PHP8 致命错误
此文章为[XIUNOX](https://link.zhihu.com/?target=https%3A//github.com/domidesign/xiunox)版本重构审计时发现问题,[XIUNOX](https://link.zhihu.com/?target=https%3A//github.com/domidesign/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 处真实调用): ```javascript // 第 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`: ```javascript // 第 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`。 危害: 1. 当 `conf['db']['type'] == 'mysql'` 时(`conf.default.php` 默认值即 `'mysql'`),站点启动即崩溃,无法连接数据库。 1. 安装向导第 81 行 `function_exists('mysql_connect')` 永远返回 FALSE,若用户未启用 PDO,会被错误提示“环境不支持”而无法继续;若选 `type=mysql`,第 135 行建库直接 Fatal error。 1. `xiunophp.min.php` 是 `DEBUG <= 1` 时的默认加载文件,影响所有生产环境。 修复建议: 1. 强制将默认 `db.type` 改为 `pdo_mysql`,从 `conf.default.php`、`conf/conf.php`、安装向导中移除 `mysql` 类型选项;或在 `db_new()` 中拒绝 `'mysql'` 类型并回退到 `pdo_mysql`。 1. 删除 `xiunophp/db_mysql.class.php` 与 `xiunophp.min.php` 中的 `class db_mysql`,统一使用 `db_pdo_mysql`。 1. `install/index.php` 第 81 行改为只检测 `pdo_mysql`,第 134-136 行的 `mysql_query("CREATE DATABASE $name")` 改为通过 PDO 执行 `CREATE DATABASE`。 1. 若必须保留 `db_mysql` 类以兼容老配置,应在 `db_mysql.class.php` 顶部 `if(!function_exists('mysql_connect')) return;` 并在 `db_new()` 中提示用户切换驱动。