You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP:如何为图片上传功能正确检查文件MIME类型?

在PHP图片上传中添加双重MIME类型检查的实现方案

你目前的扩展名校验已经做了基础防护,但确实,只靠扩展名很容易被绕过——攻击者可以把恶意文件改个后缀就蒙混过去。所以在扩展名检查的前后加上基于文件真实内容的MIME类型校验,能大大提升上传安全性。下面是修改后的完整代码,我会标注清楚新增的部分:

首先,先定义允许的MIME类型白名单(和你的扩展名白名单对应):

$aExtensionWhitelist = ['png', 'jpg', 'jpeg'];
$aMimeWhitelist = ['image/png', 'image/jpeg', 'image/jpg']; // 对应允许的图片MIME类型

然后是修改后的上传循环代码:

<?php 
$iAmountOfFiles = count($_FILES['Filename']['name']);
// 初始化finfo对象,用于读取文件真实MIME类型
$finfo = new Finfo(FILEINFO_MIME_TYPE);

while($iAmountOfFiles >= 1) {
    $iAmountOfFiles--;
    $tmpFilePath = $_FILES['Filename']['tmp_name'][$iAmountOfFiles];

    // --- 第一步:扩展名检查前的MIME校验 ---
    $fileMime = $finfo->file($tmpFilePath);
    if(!in_array($fileMime, $aMimeWhitelist)) {
        echo "Bestands type niet toegestaan (ongeldige MIME)";
        continue;
    }

    $aFileProperties = pathinfo($_FILES['Filename']['name'][$iAmountOfFiles]);
    if(!in_array(strtolower($aFileProperties["extension"]), $aExtensionWhitelist)) {
        echo "Bestands type niet toegestaan (ongeldige extensie)";
        continue;
    }

    $sTarget = ROOT.BACKEND."/pages/bezienswaardigheden-toevoegen/uploads/";
    $sUniqueFileNameHash = hash('adler32', time().rand());
    $Filename = basename($aFileProperties["filename"]."-".$sUniqueFileNameHash.".".strtolower($aFileProperties["extension"]));

    // Writes the Filename to the server
    if(move_uploaded_file($tmpFilePath, $sTarget.$Filename)) {
        // --- 第二步:文件存入服务器后的二次MIME校验 ---
        $uploadedFileMime = $finfo->file($sTarget.$Filename);
        if(!in_array($uploadedFileMime, $aMimeWhitelist)) {
            // 如果校验失败,删除已上传的恶意文件
            unlink($sTarget.$Filename);
            echo "Bestands type niet toegestaan (upload na verificatie ongeldig)";
            continue;
        }

        // 这里继续你的数据库存储逻辑...
    } else {
        echo "Upload mislukt";
    }
}
?>

关键细节说明:

  • 用Finfo类获取真实MIME类型:不同于$_FILES['Filename']['type'](这是客户端浏览器提供的,很容易伪造),Finfo会读取文件的二进制头部信息来判断真实类型,安全性更高。
  • 前置校验:在处理文件扩展名和生成文件名之前就做MIME检查,能提前拦截恶意文件,减少不必要的资源消耗。
  • 后置校验:文件上传到服务器后再次校验,防止文件在传输过程中被篡改,或者出现其他异常情况,双重保险。如果校验失败,记得删除已经上传的文件,避免恶意文件留在服务器上。

内容的提问来源于stack exchange,提问作者emmea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 13:02:51