必须服务端双重校验扩展名与mime类型,并叠加web服务器隔离和php执行禁用,缺一不可。仅依赖后台文件类型设置或前端校验极易被绕过,无法真正限制只允许.doc/.docx上传。

帝国CMS后台上传限制只允许.doc/.docx文件
默认情况下,帝国CMS的附件上传不限制具体扩展名,仅靠前端JS校验或后端简单后缀判断极易绕过。要真正实现“只允许Word文档”,必须在服务端做双重校验:既检查文件扩展名,也验证实际MIME类型和二进制特征。
修改/e/class/functions.php中的文件上传校验逻辑
帝国CMS的通用上传入口是DoUpload函数,位于/e/class/functions.php。不能只改前台JS或表单accept属性——这些全可被浏览器跳过。需直接干预该函数的校验分支:
- 找到
if($filetype=='')之后、if($filesize==0)之前的校验段 - 插入以下强制MIME+扩展名校验逻辑(注意替换原有宽松判断):
if (!in_array(strtolower($filetype), ['.doc', '.docx'])) { printerror('FileExtNotAllow', '', 1); } $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $filepath); finfo_close($finfo); if (!in_array($mime, [ 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ])) { printerror('FileMimeNotAllow', '', 1); } -
printerror调用需确保语言包中已定义FileExtNotAllow和FileMimeNotAllow错误提示
同步调整PHP和Web服务器层的兜底限制
仅改CMS代码不够。攻击者可能通过直接POST绕过DoUpload,或利用Nginx/Apache配置缺陷上传恶意文件。必须叠加基础设施层防护:
- 在PHP配置中禁用危险执行扩展:
disable_functions = exec,passthru,shell_exec,system - Nginx配置中添加
location ~* \.(doc|docx)$块,禁止该路径下执行PHP:deny all; - Apache需在
.htaccess或vhost中设置:<filesmatch>SetHandler default-handler</filesmatch> - 确认
upload_max_filesize和post_max_size在php.ini中合理(如20M),避免超大Word文档拖垮服务
为什么不能只依赖帝国CMS后台的“允许上传文件类型”设置
系统后台「系统参数设置→文件设置」里的允许上传的文件类型字段,本质只是对$filetype变量做in_array()匹配,且未校验MIME、未打开finfo扩展、未检查ZIP结构。实测发现:
- 攻击者上传伪装成
test.docx的PHP木马,只要文件头不是PK(ZIP签名),finfo会返回text/plain,但CMS仍会放行 - 某些Office漏洞可构造特殊
.docx触发远程代码执行,仅靠扩展名白名单毫无意义 - 后台设置不生效于API接口、附件批量导入、编辑器粘贴上传等非标准路径
真正的防线必须落在finfo校验+Web服务器隔离+PHP执行禁用这三层,缺一不可。任何一层松动,都可能让shell.docx变成shell.php。











