首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 檔案上傳驗證:前後端雙重檢查與檔案類型偵測

     編輯:PHP 相關知識

PHP 檔案上傳驗證:前後端雙重檢查與檔案類型偵測

前端 JavaScript 基礎檢查

<form action="?" method="post" enctype="multipart/form-data">
  檔案上傳:<input type="file" name="file" id="file"/>
  <input type="submit" id="send" value="提交"/>
</form>

<script>
document.getElementById("send").onclick = function() {
    var file = document.getElementById("file").value;
    if (file.length < 1) {
        alert('請選擇圖片');
        return false;
    }
    // 進階:限制副檔名
    var ext = file.match(/\.([^.]+)$/)[1].toLowerCase();
    if (['jpg','png','gif','pdf'].indexOf(ext) === -1) {
        alert('檔案類型不支援');
        return false;
    }
};
</script>

後端 PHP 基礎驗證

<?php
// 必須檢查 tmp_name,單檢 name 或 size 不可靠
if (!empty($_FILES['file']['tmp_name'])) {
    echo '已選擇檔案';
} else {
    echo '請選擇檔案';
}
?>

深度檔案類型偵測(讀取檔頭 Magic Bytes)

僅檢查副檔名或 MIME 不安全,需讀取檔案前 2 位元組特徵碼:

<?php
function file_type($filename) {
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); // 讀取前 2 位元組
    fclose($file);
    
    $strInfo = @unpack("C2chars", $bin);
    $typeCode = intval($strInfo['chars1'] . $strInfo['chars2']);
    
    $fileType = '';
    switch ($typeCode) {
        case 7790: $fileType = 'exe'; break;
        case 7784: $fileType = 'midi'; break;
        case 8297: $fileType = 'rar'; break;
        case 8075: $fileType = 'zip'; break;
        case 255216: $fileType = 'jpg'; break;
        case 7173: $fileType = 'gif'; break;
        case 6677: $fileType = 'bmp'; break;
        case 13780: $fileType = 'png'; break;
        default: $fileType = 'unknown: ' . $typeCode;
    }
    
    // 修正特殊情況(有號整數解讀問題)
    if ($strInfo['chars1'] == '-1' && $strInfo['chars2'] == '-40') return 'jpg';
    if ($strInfo['chars1'] == '-119' && $strInfo['chars2'] == '80') return 'png';
    
    return $fileType;
}

echo file_type('start.php'); // 輸出類型代碼
?>

常見檔案 Magic Bytes 對照

格式HexDecimal (前2字節)
JPGFF D8255 216
PNG89 50137 80
GIF47 4971 73
BMP42 4D66 77
ZIP50 4B80 75
RAR52 6182 97

安全建議

  • 前端檢查僅為使用者體驗,不可信任
  • 後端必須驗證 tmp_name 存在且讀取檔頭確認類型
  • 上傳目錄設定不可執行權限(Nginx/Apache 禁用 PHP 解析)
  • 檔案重新命名儲存,避免路徑遍歷攻擊
  • 限制上傳檔案大小(upload_max_filesize, post_max_size)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved