应先用basename剥离路径,再清除空字节,最后用白名单校验小写后缀。pathinfo直接提取不可信,因不防空字节截断;需标准化文件名后二次提取,并严格全匹配正则或in_array校验。

从用户上传的文件名中安全提取后缀,避免将恶意字符串(如“.php”、“.phtml”或带空字节的绕过payload)当作合法扩展名处理,是PHP文件上传校验的关键环节。
用pathinfo提取原始后缀
调用pathinfo($filename, PATHINFO_EXTENSION)获取扩展名,这是最直接的方式。
这一步操作起来很简单,直接传入原始文件名即可,但【它不验证路径合法性,也不过滤非法字符】——如果文件名是shell.php%00.jpg,pathinfo仍会返回jpg,而底层系统可能按php解析。
不要依赖它做安全判断,仅用于初步结构分析。
立即学习“PHP免费学习笔记(深入)”;
过滤后缀前先标准化文件名
第一步:用basename($filename)剥离路径,防止../../shell.php类攻击。
第二步:用str_replace(["\0", "%00"], "", $basename)清除空字节及URL编码空字节——【空字节截断是绕过extension检查的核心漏洞点】。
第三步:对结果再执行一次pathinfo(..., PATHINFO_EXTENSION),此时得到的后缀才具备基础可信度。
白名单校验后缀
方法一:用in_array()比对预设白名单
$allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
$ext = strtolower($ext); // 必须转小写,防止JPG绕过
if (!in_array($ext, $allowed)) { die('不支持的文件类型'); }
方法二:用正则严格匹配(更防干扰)
if (!preg_match('/^(?:jpe?g|png|gif|pdf)$/i', $ext)) { die('后缀非法'); }
注意:正则开头不用^、结尾不用$会导致php.jpg被误判为合法——必须全匹配。



















