在 PHP 開發中處理文件上傳時,伺服器需識別上傳文件的 MIME 類型(如 .jpg 對應 image/jpeg)。這項判斷首先由瀏覽器在表單提交時完成,再傳遞給 PHP 處理。然而,不同瀏覽器對同一文件的 MIME 類型定義可能不一致,導致驗證邏輯出現漏洞。本文提供 IE 與 Firefox 的常見文件類型對照表,並示範如何安全限制上傳格式。
| ID | 副檔名 | IE 識別類型 | Firefox 識別類型 |
|---|---|---|---|
| 0 | gif | image/gif | image/gif |
| 1 | jpg | image/jpeg | image/pjpeg |
| 2 | png | image/png | image/x-png |
| 3 | bmp | image/bmp | image/bmp |
| 4 | psd | application/octet-stream | application/octet-stream |
| 5 | ico | image/x-icon | image/x-icon |
| 6 | rar | application/octet-stream | application/octet-stream |
| 7 | zip | application/zip | application/x-zip-compressed |
| 8 | 7z | application/octet-stream | application/octet-stream |
| 9 | exe | application/octet-stream | application/octet-stream |
| 10 | avi | video/avi | video/avi |
| 11 | rmvb | application/vnd.rn-realmedia-vbr | application/vnd.rn-realmedia-vbr |
| 12 | 3gp | application/octet-stream | application/octet-stream |
| 13 | flv | application/octet-stream | application/octet-stream |
| 14 | mp3 | audio/mpeg | audio/mpeg |
| 15 | wav | audio/wav | audio/wav |
| 16 | krc | application/octet-stream | application/octet-stream |
| 17 | lrc | application/octet-stream | application/octet-stream |
| 18 | txt | text/plain | text/plain |
| 19 | doc | application/msword | application/msword |
| 20 | xls | application/vnd.ms-excel | application/vnd.ms-excel |
| 21 | ppt | application/vnd.ms-powerpoint | application/vnd.ms-powerpoint |
| 22 | application/pdf | application/pdf | |
| 23 | chm | application/octet-stream | application/octet-stream |
| 24 | mdb | application/msaccess | application/msaccess |
| 25 | sql | application/octet-stream | text/plain |
| 26 | con | application/octet-stream | application/octet-stream |
| 27 | log | text/plain | text/plain |
| 28 | dat | application/octet-stream | text/plain |
| 29 | ini | application/octet-stream | application/octet-stream |
| 30 | php | application/octet-stream | application/octet-stream |
| 31 | html | text/html | text/html |
| 32 | htm | text/html | text/html |
| 33 | ttf | application/octet-stream | application/octet-stream |
| 34 | fon | application/octet-stream | application/octet-stream |
| 35 | js | application/x-javascript | text/html |
| 36 | xml | text/xml | text/xml |
| 37 | dll | application/octet-stream | application/octet-stream |
| 38 | dll/class | application/octet-stream | application/java |
以下程式碼展示如何根據 MIME 類型映射副檔名,並攔截非允許格式:
<?php
$temppath = $upfile['tmp_name'];
$fileinfo = pathinfo($upfile['name']);
$extension = $upfile['type']; // 取得瀏覽器回報的 MIME 類型
switch ($extension) {
case 'application/msword':
$extension = 'doc';
break;
case 'application/vnd.ms-excel':
$extension = 'xls';
break;
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
$extension = 'docx';
break;
case 'application/vnd.ms-powerpoint':
$extension = 'ppt';
break;
case 'application/pdf':
$extension = 'pdf';
break;
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
$extension = 'xlsx';
break;
default:
die('只允許上傳 doc, docx, xls, xlsx, pdf, ppt 文件 <a href="upload.php">重新上傳</a>');
}
?>
finfo_file() 函數讀取文件真實 MIME 類型,防止偽裝文件繞過驗證。