此文章为XIUNOX版本重构审计时发现问题,XIUNOX版本已优化修复此问题。分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 的模板文件(view/htm/*.htm)并非纯模板语言,而是直接包含 代码块。模板经 _include() 编译后被原样写入 tmp/ 目录并作为 PHP 文件被 include,意味着:
- 主题(
_theme_*插件)可携带任意 PHP 代码,安装即获得代码执行。 - 模板中的 PHP 与 HTML 强耦合,无法做语法隔离、沙盒、变量过滤。
- 主题作者可轻易在 header.inc.htm 中植入
eval($_POST['x'])等后门。 - 老主题(继承自 3.0 / 4.0 早期)大量混用
,可读性差且易引入 XSS 与 RCE。
源码证据
文件:xiunobbs_4.0.4/view/htm/post_list.inc.htm(头部片段)
" class="mr-3" tabindex="-1">
">
文件:xiunobbs_4.0.4/view/htm/thread.htm(第 1 行 / 第 101 行)
...
文件:xiunobbs_4.0.4/model/plugin.func.php 第 15-37 行 —— 编译产物直接以 PHP 文件形式被 include
function _include($srcfile) {
global $conf;
// 合并插件,存入 tmp_path
$len = strlen(APP_PATH);
$tmpfile = $conf['tmp_path'].substr(str_replace('/', '_', $srcfile), $len);
if(!is_file($tmpfile) || DEBUG > 1) {
// 开始编译
$s = plugin_compile_srcfile($srcfile);
// ...
file_put_contents_try($tmpfile, $s); // 直接写入 PHP 文件
$s = plugin_compile_srcfile($tmpfile);
file_put_contents_try($tmpfile, $s);
}
return $tmpfile;
}
调用方(xiunobbs_4.0.4/index.php 第 51-52 行)直接 include _include(...):
include _include(APP_PATH.'model.inc.php');
include _include(APP_PATH.'index.inc.php');
风险等级与结论
风险等级:高(High)|生态缺陷
危害:
- 主题/插件可携带任意 PHP,无沙盒、无 opcode 限制、无函数黑名单。
- 模板与业务逻辑深度耦合,老主题升级困难,新主题作者容易引入安全漏洞。
_include()把模板编译为.htm后缀文件再include,但内容是 PHP,存在被直接访问tmp/xxx.htm暴露源码的风险(取决于服务器配置)。- 模板中大量
没有统一转义函数,XSS 风险随主题扩散。
修复建议:
- 引入模板引擎(如 Twig/Plates),禁止模板中直接出现
。 - 至少提供
xn_escape()/e()等统一转义函数,并在核心模板中替换裸echo。 - 对主题/插件上传做 PHP 关键字扫描(
eval、system、exec、shell_exec、passthru、preg_replace /e、assert、create_function),命中即拒绝安装。 tmp/目录配置.htaccess/nginx 规则禁止直接访问.htm.php文件。- 长期方案:将模板后缀改为
.tpl.php并强制exit;前缀防直接访问。