问题:附件上传仅扩展名白名单校验,含 swf/exe 危险类型且无 MIME/内容校验
此文章为XIUNOX版本重构审计时发现问题,分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 附件上传 (route/attach.php) 仅依据文件名扩展名做白名单校验,既不校验 MIME 类型,也不校验文件内容(magic bytes)。更严重的是,白名单 conf/attach.conf.php 中直接包含 swf、exe、bin 等本身具有风险的扩展名:swf 可承载 ActionScript 实现 XSS,exe/bin 可被用作恶意载荷托管。对于不在白名单的扩展名(如 php),处理方式仅为前缀加 _(变成 _php),该缓解依赖服务端解析器配置,在 Apache 多解析/IIS 路径信息泄露等场景下可能被绕过。
此外 file_ext($name, 7) 对扩展名做 7 字符截断,存在长扩展名被裁剪后意外命中白名单的边角风险。
源码证据
证据 1:上传校验仅扩展名白名单,无 MIME/内容校验 文件:xiunobbs_4.0.4/route/attach.php 行 17-47
$name = param('name');
$data = param('data', '', FALSE, FALSE);
$data = param_base64('data');
$ext = file_ext($name, 7);
$filetypes = include APP_PATH.'conf/attach.conf.php';
!in_array($ext, $filetypes['all']) AND $ext = '_'.$ext;
$tmpanme = $uid.'_'.xn_rand(15).'.'.$ext;
$tmpfile = $conf['upload_path'].'tmp/'.$tmpanme;
$tmpurl = $conf['upload_url'].'tmp/'.$tmpanme;
$filetype = attach_type($name, $filetypes);
file_put_contents($tmpfile, $data) OR message(-1, lang('write_to_file_failed'));
第 35-37 行:$ext = file_ext($name, 7); 取扩展名后 in_array 校验,不在白名单则 $ext = '_'.$ext。全程无 $_FILES['type']、finfo、getimagesize 等内容/MIME 校验。第 47 行直接 file_put_contents 落盘。
证据 2:白名单含危险扩展名 文件:xiunobbs_4.0.4/conf/attach.conf.php 行 3-6
return array (
'all'=> array('av','wmv','wav','wma','avi','rm','rmvb','mp4', 'mp3','exe','bin','swf','fla','as','gif','jpg','jpeg','png','bmp','doc','xls','ppt','docx','xlsx','pptx','pdf',
'c','cpp','cc', 'txt','tar','zip','gz','rar','7z','bz','chm','bt','torrent','ttf','font','fon'
),
白名单 all 数组中包含 exe、bin(可执行文件,恶意载荷托管)、swf(Flash,可内嵌 ActionScript 实现 XSS / 跨域请求)。攻击者可直接以 .swf 后缀上传恶意 Flash 文件,在同源环境下触发 XSS。
证据 3:file_ext 扩展名截断逻辑 文件:xiunobbs_4.0.4/xiunophp/misc.func.php 行 1011-1017
function file_ext($filename, $max = 16) {
$ext = strtolower(substr(strrchr($filename, '.'), 1));
$ext = xn_urlencode($ext);
strlen($ext) > $max AND $ext = substr($ext, 0, $max);
if(!preg_match('#^\w+$#', $ext)) $ext = 'attach';
return $ext;
}
第 1014 行:扩展名超过 $max(此处为 7)时直接 substr 截断,长扩展名被裁剪后可能产生非预期匹配。
风险等级与结论
风险等级:高危
结论:
- 上传校验仅基于文件名扩展名,无 MIME 类型校验、无文件内容(magic bytes)校验,攻击者可任意伪造扩展名上传。
- 白名单本身包含
swf/exe/bin 等危险类型,.swf 可直接用于同源 XSS,.exe/.bin 可作为恶意载荷分发入口。
- 非白名单扩展名仅加
_ 前缀(_php),该缓解在 Apache mod_mime 多解析、IIS CGI 路径信息、上传目录 .htaccess 失控等场景下可能失效,导致代码执行。
file_ext 7 字符截断存在边角绕过风险。
- 修复建议:白名单移除
swf/exe/bin;引入 finfo_file/getimagesize 做内容校验;非白名单扩展名直接拒绝而非加 _ 前缀;上传目录禁止 PHP 解析(.htaccess / Nginx 配置);附件下载强制 Content-Disposition: attachment 并设 X-Content-Type-Options: nosniff。