При обработке загруженных файлов $_FILES['foo']['type']
не является абсолютно надежным. Я обнаружил, что если вы измените расширение на OS X, «тип» будет изменен автоматически.
Вместо этого рассмотрим:
$fileInfo = new \finfo(FILEINFO_MIME); $mimeType = $fileInfo->buffer(file_get_contents($_FILES['foo']['tmp_name'])); $mimeType = explode(';', $mimeType);
Теперь, если я переименую PHP-скрипт на .jpg и выгружаю его (в OS X 10.10) $_FILES['foo']['type']
= image/jpeg
и $mimeType
= text/x-php
.
Тип файла можно легко изменить, но как можно сфокусировать finfo :: buffer PHP? В чем разница между тем, что проверил PHP для $_FILES['foo']['type']
и finfo(FILEINFO_MIME)
?
PHP не проверяет ничего в $_FILES
; при загрузке файла отправляющий браузер отправляет метаданные того, что он считает типом файла. $_FILES['file']['type']
просто отражает это значение, загруженное браузером. Очевидно, что любой может подделать это по своему усмотрению.
Finfo использует волшебную базу данных , которая представляет собой просто набор идентификационных характеристик типов файлов. Т.е. все файлы JPEG имеют характерный заголовок, все файлы ZIP начинаются определенным образом, этот тип файла имеет такое количество ведущих байтов, этот тип файла имеет такие виды конечных байтов и т. Д. И т. Д. Это труднее обмануть, если вы на самом деле хотите создать допустимый файл определенного типа, но отнюдь не невозможно.
$_FILES
получает его тип из заголовка Content-Type части mime, которая содержит файл. Эта часть создается тем, что отправляет файл, обычно браузер, который угадает тип на основе расширения файла.
С другой стороны, расширение fileinfo основывается на библиотеке magic_open. Если я правильно помню, magic_open проверит несколько атрибутов файла, включая заголовки файлов, чтобы определить тип mimetype. Попробуйте вставить php в html-файл. Я считаю, что поскольку заголовок файла <!DOCTYPE html>
он определит, что text/html
является типом mime.