Xiuno BBS 审计之问题06:硬编码 auth_key 加密密钥

问题:默认配置硬编码 auth_key 加密密钥

此文章为XIUNOX版本重构审计时发现问题,分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。

现象

Xiuno BBS 4.0.4 默认配置文件 conf/conf.default.php 中硬编码了 auth_key 加密密钥 'efdkjfjiiiwurjdmclsldow753jsdj438'。该密钥是全站加密体系的核心:xn_key() 返回它作为 xn_encrypt/xn_decrypt(XXTEA)的密钥,用于加密 bbs_token(用户登录态)、bbs_admin_token(后台登录态)等鉴权令牌。

由于该值在源码中公开硬编码:

  • 任何获取源码的人(Xiuno BBS 为开源项目)均知道该默认密钥。
  • 若管理员未在安装时修改 auth_key(安装脚本 install/index.php 行 194 会生成随机 auth_key 覆盖,但仅当正常走安装流程时;若用户手动复制 conf.default.phpconf.php 则保留硬编码值),则全站令牌加密形同虚设,攻击者可用公开密钥伪造任意用户/管理员的 bbs_token/bbs_admin_token

源码证据

证据 1:默认配置硬编码 auth_key 文件:xiunobbs_4.0.4/conf/conf.default.php 行 87

php 复制代码
'auth_key' => 'efdkjfjiiiwurjdmclsldow753jsdj438',

该 33 字符字符串硬编码在源码中,Xiuno BBS 为公开开源项目,该值对任何人均可见。

证据 2:xn_key 直接使用 auth_key 作为加密密钥 文件:xiunobbs_4.0.4/xiunophp/xn_encrypt.func.php 行 16-19

php 复制代码
function xn_key($fromso = TRUE) {
	$conf = _SERVER('conf');
	return ($fromso && function_exists('xiuno_key')) ? xiuno_key() : (isset($conf['auth_key']) ? $conf['auth_key'] : '');
}

第 18 行:未加载 xiuno.so 扩展时,直接返回 $conf['auth_key'] 作为所有 xn_encrypt/xn_decrypt 调用的密钥。

证据 3:auth_key 用于加密用户/后台鉴权令牌 文件:xiunobbs_4.0.4/model/user.func.php 行 348-358

php 复制代码
function user_token_gen($uid) {
	global $ip, $time, $conf;
	$tokenkey = md5(xn_key());
	$token = xn_encrypt("$ip	$time	$uid", $tokenkey);
	return $token;
}

文件:xiunobbs_4.0.4/admin/admin.func.php 行 47-62

php 复制代码
function admin_token_set() {
	global $longip, $time, $useragent, $conf;
	$useragent_md5 = md5($useragent);
	$key = md5((XN_ADMIN_BIND_IP ? $longip : '').$useragent_md5.xn_key());
	$admin_token = param('bbs_admin_token');
	$s = "$longip	$time";
	$admin_token = xn_encrypt($s, $key);
	setcookie('bbs_admin_token', $admin_token, $time + 3600, '',  '', 0, TRUE);
}

bbs_token 的密钥为 md5(xn_key()) = md5(auth_key)bbs_admin_token 的密钥为 md5(useragent.xn_key())。若 auth_key 为公开硬编码值,攻击者已知 auth_key 即可计算 tokenkey,进而用 xn_encrypt("$ip\t$time\t$uid", tokenkey) 伪造任意 uid 的 bbs_token,或用 xn_encrypt("$longip\t$time", key) 伪造 bbs_admin_token,实现未授权登录任意账号/后台。

证据 4:安装脚本虽生成随机 auth_key,但仅限正常安装流程 文件:xiunobbs_4.0.4/install/index.php 行 192-196

php 复制代码
$replace = array();
$replace['db'] = $conf['db'];
$replace['auth_key'] = xn_rand(64);
$replace['installed'] = 1;
file_replace_var(APP_PATH.'conf/conf.php', $replace);

第 194 行安装时生成 64 位随机 auth_key 覆盖默认值。但若用户未走安装脚本(如手动 cp conf.default.php conf.php 并改数据库配置),或安装脚本因 install 目录未清理被重复执行(见独立审计文件),auth_key 可能保留硬编码值或被重置。

风险等级与结论

风险等级:高危

结论:

  1. 默认配置硬编码 auth_key='efdkjfjiiiwurjdmclsldow753jsdj438',开源项目下该值公开可知。
  2. auth_keybbs_token/bbs_admin_token 加密密钥的根,泄露后攻击者可伪造任意用户/管理员令牌,实现未授权登录与后台接管。
  3. 安装脚本虽生成随机值覆盖,但存在"手动配置未走安装流程""install 目录未清理被重复执行"等场景导致硬编码值残留。
  4. 叠加 XXTEA 弱加密(见独立审计文件)与 Cookie 无 Secure/SameSite,密钥泄露后伪造令牌可直接接管账户。
  5. 修复建议:移除硬编码默认值,强制安装时生成≥32 字节随机密钥并校验 auth_key !== 默认值;启动时检测 auth_key 是否为已知硬编码值,若是则拒绝运行并提示重置;密钥派生使用 HKDF,避免直接使用原始 auth_key;提供密钥轮换机制。
相关推荐
mldong7 小时前
从 mldong 到 jeeflow:一个工作流引擎的独立进化
后端
陈随易7 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
Aaron - Wistron8 小时前
Web API C# (Furion版)带 单元测试
开发语言·后端·c#
卷无止境8 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境8 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
IT_陈寒10 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端
SomeB1oody11 小时前
【RustyML入门】1.0. 快速上手
开发语言·后端·机器学习·rust·教程
史呆芬11 小时前
分布式事务实战:微服务跨服务数据一致性解决方案
java·后端·spring cloud