游客发表

文件上传漏洞修复

发帖时间:2026-10-17 05:06:19

去年冬天,文件一个做电商的上传朋友半夜给我打电话,说网站被挂了博彩页面。漏洞我让他查日志,修复发现攻击者上传了一个伪装成商品图的文件 PHP 文件。文件名是上传 product_123.jpg.php,服务器直接把它当脚本执行了。漏洞这事儿不新鲜,修复但每次遇到都让人窝火——明明只是文件上传功能,怎么就成了后门?上传

文件上传漏洞的根子,往往不在上传本身,漏洞而在“信任”。修复前端校验?文件改个 JS 就能绕过。MIME 类型?上传抓包改一下 Content-Type 就骗过去了。很多开发者觉得后端检查后缀名就万事大吉,漏洞可攻击者用 .phtml、.php5、.pht 照样能跑。更别提 Apache 的 .htaccess 文件,传上去就能重新定义解析规则。我见过一个案例,上传目录里混进了一个 .htaccess,里面写着 AddType application/x-httpd-php .jpg,结果所有 jpg 都成了 PHP 木马。

修复这事,得从三个层面动手。第一层,把上传目录和脚本执行彻底隔离。Nginx 里加一段 location ^~ /uploads/ { location ~ \.php$ { return 403; } },Apache 则关掉 php_admin_flag engine off。别嫌麻烦,这是底线。第二层,文件名不能信。用户传上来的名字一律丢弃,用服务端生成的 UUID 加白名单后缀。白名单要短:jpg、png、gif、pdf 就够了,别加 php、jsp、asp 这些。第三层,文件内容得验。图片用 getimagesize() 读一下,PDF 检查 %PDF- 头。有人图省事只查后缀,结果传了个 shell.jpg,里面全是 PHP 代码,服务器照样中招。

还有几个坑我踩过。比如上传路径拼接,move_uploaded_file 的目标路径如果用了 ../,能直接写到 Web 根目录外面去。再比如临时文件竞争,PHP 的 upload_tmp_dir 里文件在脚本结束前一直存在,攻击者用多线程抢在删除前访问,也能拿到 shell。这些细节不写进代码审查清单,迟早出事。

我习惯在修复后做一次“自攻”。写个脚本,模拟传 test.php.jpg、test.jpg.php、test.pHp、test.php%00.jpg(老版本 PHP 的截断),看服务端返回什么。再传一个正常图片,确认功能没坏。最后用 curl -F "file=@shell.php;type=image/jpeg" 试试,如果返回 403 或者文件被重命名成 .jpg 且内容被剥离,才算过关。

说句实在话,文件上传漏洞修起来不复杂,复杂的是开发者的侥幸心理。“先上线,回头再补”——回头往往就是被拖库的时候。我见过一个政府站,上传接口连后缀都不查,传个 .jsp 直接拿服务器。修复方案写了三页,最后卡在“业务部门说文件类型太多,白名单不够用”。那就折中:允许上传的类型走白名单,其他类型强制转成 .bin 并放在非 Web 目录,下载时用后端脚本读取。安全不是砍功能,是换条路走。

最后提一句日志。上传接口的日志要记全:原始文件名、生成文件名、文件大小、MIME、上传者 IP、时间戳。哪天真被传了马,至少能顺着日志找到入口。别等出了事才翻 access.log,那时候早被清干净了。

    热门排行

    友情链接