文件上传的三种白名单,和3种黑名单,以及3种针对文件内容的修改,特性、get,post传参方式区别,正则匹配,以及高亮函数作用 一、黑白名单一3 种白名单校验方式白名单核心只放行符合规则的文件其余全部拒绝。后缀名白名单逻辑预定义允许上传的文件后缀如.jpg/.png/.pdf仅校验文件名后缀匹配时放行。示例PHPphp运行$allowedExts [jpg, png, gif]; $ext pathinfo($_FILES[file][name], PATHINFO_EXTENSION); if (!in_array(strtolower($ext), $allowedExts)) { die(仅允许上传图片文件); }特点最常用但需注意大小写如.JPG转小写、多后缀绕过如test.jpg.php。MIME 类型白名单逻辑校验 HTTP 请求头中Content-Type仅允许指定类型如image/jpeg、image/png。示例PHPphp运行$allowedMime [image/jpeg, image/png, image/gif]; $mime $_FILES[file][type]; if (!in_array($mime, $allowedMime)) { die(MIME类型非法); }特点易被抓包篡改如把application/x-php改为image/jpeg需配合其他校验。文件头魔数白名单逻辑校验文件二进制开头的固定标识魔数如 JPG 以FF D8 FF开头、PNG 以89 50 4E 47开头仅匹配放行。示例PHPphp运行$file fopen($_FILES[file][tmp_name], rb); $header fread($file, 4); // 读取前4字节 fclose($file); $allowedHeader [ffd8ff, 89504e47, 47494638]; // JPG/PNG/GIF if (!in_array(bin2hex($header), $allowedHeader)) { die(文件内容非法); }特点最可靠的白名单方式直接校验文件实际内容不易被绕过。二3 种黑名单校验方式禁止特定内容黑名单核心拒绝指定的危险内容其余放行风险高易被绕过。后缀名黑名单逻辑禁止危险后缀如.php/.php5/.jsp仅拒绝匹配的后缀。示例PHPphp运行$forbidExts [php, php5, php7, jsp]; $ext pathinfo($_FILES[file][name], PATHINFO_EXTENSION); if (in_array(strtolower($ext), $forbidExts)) { die(禁止上传脚本文件); }绕过方式使用黑名单外的后缀如.php4/.phtml、空格 / 点绕过test.php.、大小写Test.PHP。关键词黑名单逻辑扫描文件名 / 文件内容中是否包含危险关键词如?php、eval(、system(包含则拒绝。示例PHPphp运行$content file_get_contents($_FILES[file][tmp_name]); $forbidKeywords [?php, eval(, system(]; foreach ($forbidKeywords as $kw) { if (strpos($content, $kw) ! false) { die(文件包含危险代码); } }绕过方式编码如base64_decode、变形?替代?php、注释截断。文件大小黑名单反向限制逻辑禁止超大文件如超过 10MB本质是 “拒绝不符合大小的文件”属于黑名单逻辑。示例PHPphp运行if ($_FILES[file][size] 10 * 1024 * 1024) { die(文件超过10MB禁止上传); }绕过方式分片上传、压缩后上传再解压。三3 种针对文件内容的修改绕过 / 加固文件内容修改是上传漏洞的核心利用 / 防御手段常见方式图片马文件内容拼接逻辑将 PHP 代码嵌入图片文件尾部 / 头部保留图片魔数绕过文件头校验上传后通过解析漏洞执行。示例bash运行# 命令行拼接将shell.php内容写入test.jpg尾部 copy /b test.jpg shell.php webshell.jpg防御上传后重新编码图片如imagecreatefromjpeg重新生成清除嵌入的代码。代码编码 / 混淆绕过关键词检测逻辑对危险代码进行 base64、十六进制编码上传后通过解码函数执行。示例PHPphp运行# 混淆后的代码绕过关键词检测 ?php eval(base64_decode(ZXZhbCgkX1BPU1RbJ2MnXSk7)); ?防御解码后再检测关键词、限制eval/assert等危险函数。文件内容截断绕过后缀校验逻辑利用 0x00 截断PHP 5.3.4或换行符修改文件名 / 内容中的后缀标识。示例抓包修改文件名test.php%00.jpg0x00 截断服务器解析为test.php内容在代码后加\0截断绕过关键词扫描。防御升级 PHP 版本、过滤文件名中的特殊字符%00、\0、换行符。二、PHP 特性 GET/POST 传参区别抓包视角一核心 PHP 特性与文件上传相关文件上传相关超全局变量$_FILES存储上传文件信息name/type/tmp_name/size/error解析特性.php后缀的文件会被 PHP 解析器执行.phtml/.php5等后缀若配置了AddType application/x-httpd-php .phtml也会解析短标签? ?等价于?php echo ?可绕过?php关键词检测路径处理pathinfo()取后缀时若文件名含多个点如test.php.jpg仅取最后一个后缀临时文件上传的文件先存到php.ini中upload_tmp_dir目录脚本结束后自动删除需手动移动move_uploaded_file。二GET/POST 传参区别抓包对比维度GET 传参POST 传参抓包位置请求行URL 后如GET /test.php?name123 HTTP/1.1请求体Header 后空行如name123age20数据类型仅 ASCII 字符无法传二进制支持任意类型二进制 / 文件如multipart/form-data长度限制受浏览器 / 服务器限制如 URL 长度≤2KB无默认限制可通过php.ini的post_max_size配置抓包示例文件上传无法传文件仅 URL 参数Content-Type: multipart/form-data; boundary----WebKitFormBoundaryxxx包含文件二进制内容参数可见性暴露在 URL 中日志 / 历史记录隐藏在请求体中相对安全PHP 接收方式$_GET[name]或$_REQUEST$_POST[name]或$_FILES文件三、正则匹配 高亮函数作用一正则匹配文件上传中常用正则是校验文件名 / 内容的核心手段PHP 中常用函数preg_match()、preg_replace()。常见正则示例校验图片后缀/^\.(jpg|png|gif)$/ii 表示忽略大小写检测 PHP 标签/\?php/i匹配?php忽略大小写过滤特殊字符preg_replace(/[^\w\.]/, , $filename)仅保留字母 / 数字 / 下划线 / 点。注意事项正则边界必须加^开头和$结尾否则会匹配部分内容如/jpg/会匹配testjpg.txt贪婪匹配默认贪婪需用?非贪婪如/\.(php).*$/会匹配test.php.jpg的.php.jpg。二高亮函数作用PHP 高亮函数用于代码语法高亮核心是highlight_file()/highlight_string()在文件上传漏洞中需重点关注功能highlight_file($filename)输出指定文件的内容并按 PHP 语法高亮添加 HTML 标签highlight_string($str)高亮字符串中的 PHP 代码。安全风险若未校验权限攻击者可通过highlight_file($_GET[file])读取服务器任意文件如highlight_file(/etc/passwd)若上传的图片马被高亮函数输出会暴露嵌入的 PHP 代码但不会执行仅泄露。防御限制高亮的文件路径如仅允许./upload/目录过滤../等路径遍历字符。总结文件上传安全白名单优先魔数 后缀 MIME黑名单易被绕过文件内容修改核心是 “保留合法标识 嵌入危险代码”GET/POST 核心区别GET 传参在 URL短 / ASCIIPOST 在请求体支持大文件 / 二进制正则匹配需注意边界和贪婪模式高亮函数需限制路径避免文件读取漏洞。