PHP 7.3中文件名重命名不当非漏洞本身,而是导致绕过类型限制、触发解析漏洞或执行恶意脚本的关键环节;必须丢弃$_FILES'file',用uniqid()+random_bytes()生成随机文件名,绑定白名单后缀,并隔离存储路径+禁用执行权限。

PHP 7.3 中文件名重命名不当本身不是漏洞,而是导致漏洞的关键环节——它会让攻击者保留对上传后文件名的控制权,从而绕过类型限制、触发解析漏洞或直接执行恶意脚本。真正要解决的是“未安全重命名”带来的风险链,核心是切断用户输入与最终文件名之间的映射关系。
必须丢弃原始文件名
用户提交的 $_FILES['file']['name'] 是完全不可信的,可能包含:
· 双扩展名(如 shell.php.jpg)
· 路径遍历(如 ../../etc/passwd 或 img/../../shell.php)
· 特殊字符或空字节(用于绕过某些旧版过滤)
· 伪装成图片但实际含 PHP 代码的“图片马”文件名
正确做法:彻底忽略原始文件名,不拼接、不截取、不正则替换,只用它做日志记录或前端提示。
使用强随机+固定后缀生成新文件名
推荐组合方式(兼顾唯一性、不可预测性、可维护性):
立即学习“PHP免费学习笔记(深入)”;
-
uniqid() + random_bytes(8) + base64_encode():例如
uniqid('up_').bin2hex(random_bytes(8))→up_68a2f1c4b9e3d5a7 - 再拼上严格校验后的安全扩展名(来自白名单,非用户输入):如
$newName = $randomPart . '.jpg'; - 避免使用时间戳、递增ID、用户名等可预测字段,防止批量猜测
配合存储路径隔离与执行禁用
即使重命名到位,若文件存放在 Web 可访问目录且服务器允许执行,仍可能被利用:
- 上传目录应设在 Web 根目录之外,例如
/var/www/uploads/→ 实际路径为/data/uploads/ - 若必须放 Web 目录下(如共享主机),需通过服务器配置禁止执行:
– Apache:在上传目录下放.htaccess,内容为php_flag engine off或Deny from all
– Nginx:在 location 块中加deny all;或fastcgi_intercept_errors on; - PHP 配置中确保
disable_functions包含exec,passthru,shell_exec,system等(虽不能替代逻辑防护,但属纵深加固)
别忘了扩展名和内容双重绑定
重命名只是第一步,还需确保新文件名的后缀与真实内容一致:
- 用
finfo_file()检查 MIME 类型,拒绝text/plain或application/x-php - 对图片类文件,调用
getimagesize()或 GD 库加载验证,失败即拒收 - 白名单只允许可信后缀(
['jpg','jpeg','png','gif','pdf']),黑名单无效 - 最终保存时,后缀必须来自白名单校验结果,而非用户或原始文件名



















