一、文件上传漏洞的攻击原理
文件上传漏洞的本质是服务器未对用户上传的文件进行充分校验,导致攻击者可以将恶意文件上传到服务器。最常见的利用方式就是上传WebShell,通过WebShell攻击者可以执行任意系统命令,浏览服务器文件,获取数据库连接信息甚至提权拿下整个服务器。
攻击者的绕过手段在不断演进:修改Content-Type请求头、使用双扩展名如shell.php.jpg、在图片文件中嵌入PHP代码、利用条件竞争在文件被删除前临时执行等。理解攻击原理才能针对性地构建防御体系。
二、文件类型校验策略
文件类型校验不能仅依赖客户端的JavaScript验证,这是最容易被绕过的防线。服务端应多层次验证:首先检查文件扩展名是否在白名单内,建议只允许jpg、png、gif、pdf等安全类型,其次校验MIME Type与扩展名是否一致,最后也是最可靠的方式是读取文件头魔数Magic Number进行验证。
图片文件的魔数标识如FFD8FF对应JPEG、89504E47对应PNG,如果文件头与扩展名不匹配应直接拒绝。对于需要上传非图片文件的场景,建议对上传接口进行更严格的权限控制。
三、文件重命名与存储分离
上传后的文件应统一重命名,推荐使用UUID或时间戳加随机数的方式生成新文件名,避免攻击者直接猜测或遍历文件名。原文件名可存入数据库供下载时展示,但服务器上不应保留原始文件名。
存储位置方面,所有上传文件应放在Web根目录之外,通过专用的下载脚本提供访问。这样即使上传了恶意脚本,也无法通过浏览器直接访问和执行。存储目录权限设置只读或禁止执行脚本。
四、文件内容安全检测
对于图片类文件,建议使用图像处理库重新生成缩略图,这不仅能压缩图片,还能清除嵌入在EXIF信息中的恶意代码。对于PDF等文档文件,可配置专门的防病毒扫描服务。对于压缩包文件,解压前应检测文件数量和解压后大小,防止压缩炸弹攻击。
内容检测还可以结合静态分析工具,扫描文件是否包含eval、system、exec等危险函数特征。上传日志应完整记录上传者IP、原始文件名、文件大小等信息,便于事后追溯。
五、条件竞争与并发防护
部分场景下文件上传后需要经过审核才能公开,但攻击者可以利用文件写入与移动之间的时间差进行条件竞争攻击。解决方案是先写入临时目录,完成所有安全检查后再移动到正式目录,且临时目录禁止执行脚本权限。
并发场景下应使用文件锁或数据库事务确保原子性操作。上传接口还应限制每用户每IP的上传频率和总量,防止被用作文件存储服务器导致磁盘耗尽。