此文章为XIUNOX版本重构审计时发现问题,XIUNOX版本已优化修复此问题。分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 配置采用 PHP 文件 return array(...) 形式,配置项混合数据库密码、SMTP 密码、auth_key 等敏感信息与站点名称、分页大小等业务配置。无环境隔离(dev/test/prod 共用 conf/conf.php)、无 .env 机制、无配置加密、无配置版本管理。后台修改配置时通过 file_replace_var() 直接重写 PHP 文件(先 include 取数组、array_merge 后 var_export 写回),既不安全也易出错。
源码证据
1. conf.default.php 直接 return array,明文存储数据库密码与 auth_key
文件:xiunobbs_4.0.4/conf/conf.default.php 第 11-87 行
return array (
'db' => array (
'type' => 'mysql',
'mysql' => array (
'master' => array (
'host' => 'localhost',
'user' => 'root',
'password' => 'root', // 明文密码
'name' => 'test',
'tablepre' => 'bbs_',
'charset' => 'utf8',
'engine' => 'innodb',
),
'slaves' => array (),
),
),
// ...
'auth_key' => 'efdkjfjiiiwurjdmclsldow753jsdj438', // 硬编码加密密钥
'version' => '4.0.4',
'static_version' => '?1.0',
'installed' => 0,
);
2. index.php 直接 include conf.php,无环境判断
文件:xiunobbs_4.0.4/index.php 第 25-32 行
$conf = (@include APP_PATH.'conf/conf.php') OR exit('window.location="install/"');
// 兼容 4.0.3 的配置文件
!isset($conf['user_create_on']) AND $conf['user_create_on'] = 1;
!isset($conf['logo_mobile_url']) AND $conf['logo_mobile_url'] = 'view/img/logo.png';
// ...
$conf['version'] = '4.0.4';
无 getenv()、无 env() 函数、无 .env 文件加载,所有环境差异需手工修改 conf.php。
3. file_replace_var 直接重写 PHP 配置文件
文件:xiunobbs_4.0.4/xiunophp/misc.func.php 第 901-923 行
function file_replace_var($filepath, $replace = array(), $pretty = FALSE) {
$ext = file_ext($filepath);
if($ext == 'php') {
$arr = include $filepath; // include 取数组
$arr = array_merge($arr, $replace);
$s = ""; // var_export 写回
file_backup($filepath);
$r = file_put_contents_try($filepath, $s);
$r != strlen($s) ? file_backup_restore($filepath) : file_backup_unlink($filepath);
return $r;
} elseif($ext == 'js' || $ext == 'json') {
// ...
}
}
后台 admin/route/setting.php 等保存配置时调用此函数重写 conf.php,存在以下风险:
var_export生成的 PHP 文件若被攻击者写入任意键值,可注入代码- 并发写入时 flock 锁粒度仅文件级,配置丢失风险
- 配置文件被改后无版本历史(仅 1 个 .backup 备份)
4. 插件配置 conf.json 同样明文存储敏感信息
文件:xiunobbs_4.0.4/model/plugin.func.php 第 157 行
file_replace_var(APP_PATH."plugin/$dir/conf.json", array('enable'=>1), TRUE);
插件配置(可能含第三方 API Key、SMTP 密码)以 JSON 明文存放于 plugin/xxx/conf.json,web 可访问目录下。
5. SMTP 配置单独文件,仍为 return array
文件:xiunobbs_4.0.4/conf/smtp.conf.php 第 1 行
route/user.php 第 341 行直接 include:
$smtplist = include _include(APP_PATH.'conf/smtp.conf.php');
SMTP 服务器、账号、密码将以明文数组形式被业务代码直接读取。
6. 配置写入 $_SERVER 充当运行时配置容器
文件:xiunobbs_4.0.4/xiunophp/xiunophp.php 第 106 行
$_SERVER['conf'] = $conf;
配置同时存在于 $conf global 与 $_SERVER['conf'],运行时修改任一处不同步。
风险等级与结论
架构缺陷(中)
危害:
- 数据库密码、auth_key、SMTP 密码明文存储于 PHP 文件,git 仓库泄露即全部沦陷
- 无环境隔离,dev/test/prod 配置混淆,开发环境易误连生产库
file_replace_var重写配置文件存在并发丢配置、注入风险- 配置项业务/敏感/运行时混杂,无法按需加密、按需加载
- 无配置中心、无热更新,修改配置需重写文件 + 清缓存
$_SERVER['conf']与$conf双轨制,运行时修改不同步
修复建议:
- 引入
.env文件 +getenv()读取敏感配置(密码、密钥、API Key) - 业务配置(站点名、分页大小)保留 PHP 文件,敏感配置移至环境变量
- 配置加载改为不可变对象(Config immutable),运行时禁止修改
file_replace_var改为原子写入(临时文件 + rename),并发安全- 引入配置中心(如 etcd/Apollo)支持热更新与版本回滚
.gitignore排除conf/conf.php、.env,仓库仅保留conf.default.php模板