PHP 文件上传安全清单:扩展名白名单只是第一道门

CLARA轻量论坛系统
CLARA轻量论坛系统 星耀SVIP管理员 黑卡会员
发布于 2026-09-15 12:44 ·14 浏览 ·0 回复

结论:扩展名白名单只是第一道门,真正能挡住 PHP webshell 的是「白名单 + 真实类型校验 + 随机重命名 + 存储目录禁止执行」四件套一起上,少一件都可能在某个服务器配置下被绕过。

为什么白名单挡不住全部上传攻击

结论:白名单能筛掉九成顺手尝试,但它管不住「服务器怎么解析这个文件」这件事。

常见的绕过路径有四类。一是黑名单思维,只禁了 php,却漏了 phtml、pht、php5、php7,以及大小写混写和结尾加点加空格(Windows 会自动去掉尾部点号)。二是 MIME 伪造,Content-Type 是客户端给的,抓包改一个字段就能伪装成 image/jpeg。三是命名绕过,用户原始文件名里带 `../` 造成路径穿越,或者上传 .htaccess 反向改写解析规则。四是服务器配置本身,Apache 的 AddHandler 支持多扩展名匹配,Nginx 里 `location ~ \.php` 如果没严格锚定结尾,`evil.jpg/x.php` 这类路径就可能被当脚本执行。

所以白名单是门槛,不是墙。真正的墙在文件落盘之后:这个文件到底能不能被当成脚本跑起来。

服务端最小可用清单(照着做)

结论:扩展名用数组严格比对、文件用随机名落盘、目录禁止执行脚本,这三步做完才算及格。

步骤一,安全地取扩展名。 先 `basename()` 去掉路径,再 `strtolower()`,再 `pathinfo($file, PATHINFO_EXTENSION)`,最后 `in_array($ext, $allowList, true)` 严格比较。别用 explode('.') 取最后一段就信了。

步骤二,对图片做二次校验。 用 `getimagesize()` 或 `finfo_file()` 读真实文件头,MIME 不在 jpeg/png/gif/webp 之内一律丢弃。这一步专治「改了扩展名的马」。

步骤三,重命名落盘。 例如 `$name = bin2hex(random_bytes(16)) . '.' . $ext`,永远不要用用户传上来的原始文件名,也别让上传目录可被枚举。

步骤四,让上传目录只能读不能跑。 Nginx 里单独加一段:`location ^~ /uploads/ { location ~ \.php$ { deny all; } }`;Apache 侧在 uploads 下放 .htaccess 关掉引擎或拒绝脚本。这一条比任何白名单都硬。

步骤五,限额与权限。 PHP 的 `upload_max_filesize` 与 `post_max_size` 必须大于你允许的最大文件,宝塔默认 2M、手机照片经常超,建议调到 30M 以上;上传接口同样要走 CSRF 校验和登录态判断,别做成谁都能调的裸接口。

三个常被忽略的环节:权限、报错、日志

结论:上传是「谁能传、能传多大、传失败为什么」的组合题,只校验文件本身并不完整。

权限维度上,不是所有用户都该有上传权。Clara BBS 的做法是把它放进权限矩阵——版块级的浏览/发帖/回复/上传按用户组分别配置,留空继承;图片上传与表情包还被归为会员专属权益,普通用户需开通含该权益的套餐,管理员豁免。

报错维度上,失败必须给出具体原因,否则你会把「PHP 上限」误判成「代码有 bug」。Clara BBS 会明确提示是超过 PHP 上限、白名单不符还是目录不可写,这是排查的第一手线索。

日志维度上,谁在什么时间传了什么、来自哪个 IP,出问题时是唯一的追溯依据。

Clara BBS 里对应的实现与排查方式

结论:如果用的是 Clara BBS,官方已提供白名单与图片二次校验,但服务器层的「禁止执行」仍需自己确认。

它的安全基线写得很直白:全站 CSRF 防护、密码 bcrypt、输出转义、上传文件类型白名单加图片二次校验。注意后台有两个独立字段——「系统设置→上传」里的「允许的扩展名」管图片,「附件允许的扩展名」管附件,很多人改完前者发现附件还是传不上去,就是这里没分清。

图片上传失败的标准三步排查:① 看这两个扩展名字段是否包含目标格式;② 看 `upload_max_filesize` / `post_max_size` 是否大于文件体积;③ 看 uploads 目录是否可写。

另外两个降风险的设计值得借鉴:附件可单独定价出售,并能限定「所有人 / 会员 / 指定用户组」下载;还支持网盘链接模式附件,只存链接与提取码、不占服务器存储——本质上是把「托管不可信文件」这件事外包了出去,安全面自然小一圈。

收尾

把清单合起来就一句话:白名单不要用黑名单思维,扩展名之外要看真实 MIME 与图片文件头,落盘一律随机重命名,最后必须在 Web 服务器层面让上传目录执行不了 PHP;再配上权限、限额、报错与日志四项配套。少了目录禁止执行那一条,前面三步都只是在赌服务器配置没写错。

本文转载自 Clara轻量论坛系统,原文地址:https://www.leleweb.cn/thread-373.html
转载请注明出处,版权归原作者所有。
他们都看过 1 人浏览过
CLARA轻量论坛系统

全部回复 0

还没有回复,来抢沙发~