В основном вы делаете это правильно. Вы никогда не должны полагаться на заголовки типа mime, которые отправляются из формы загрузки, потому что вы можете легко их подделать или нет, тогда вы часто будете получать заголовок application/octet-stream
.
Таким образом, было бы неплохо проверить, соответствует ли расширение файла разрешенному типу mime для этого расширения файла.
Я видел, что вы связали этот список here. Подмигнули, безусловно, хороший список, но на самом деле не использовать для PHP, потому что в массиве слишком много ovverriden, например:
$mimeTypes = array(
'xlm' => 'application/vnd.ms-excel',//overridden
'xlm' => 'application/x-excel',
'xls' => 'application/excel',//overridden
'xls' => 'application/vnd.ms-excel'
);
var_dump($mimeTypes);
Это будет выводиться только два значения, а не четыре, вы должны использовать массив, как это:
$mimeTypes = array(
'xlm' => array('application/vnd.ms-excel', 'application/x-excel'),
'xls' => array('application/excel', 'application/vnd.ms-excel'),
'txt' => array('text/plain')
);
var_dump($mimeTypes);
Таким образом, вы можете просто проверить MimeType с in_array(), если у вас уже есть файл с расширением.
Это основной пример того, как вы могли его решить. Примечание: Это не рабочий пример, но я думаю, что вы знаете, где я хочу отметить:
// you have your file, you said it´s excel but you uploaded it with extension txt
$filepath = "excel.txt";
if(strpos($filepath, '.') === false) {
// no file extension
// return ?
}
// get the file extension
// well there is surely a better way
$filenameParts = explode(".", $filepath);
$fileExt = array_pop($filenameParts);// return the las element of the array and REMOVES it from the array
// your fopen stuff to get the mime type
// ok let´s say we are getting back the follwing mime type
$fileMimeType = 'application/vnd.ms-excel';
// now check if filextension is in array and if mimetype for this extension is correct
if(isset($mimeTypes[$fileExt]) && in_array($fileMimeType, $mimeTypes[$fileExt])) {
// file extension is OK AND mime type matches the file extension
} else {
// not passed unknown file type, unknown mime type, or someone tricked you
// your excel.txt should end up here
}
как вы убедитесь, что тип файла «приложение/октет-поток», если вы сделали это в массиве файлов он не является надежным, он может легко подделаться. Заголовок файла «application/octet-stream» отправляется, если ни один не распознается. что не всегда ** не всегда ** означает, что загруженный файл имеет этот тип. Вы должны проверить загруженный файл, а не массив $ _FILES для mime-типов. – swidmann
octet-stream возвращается из finfo :: buffer. Затем я получил mimetype расширения xsl из массива, это был x-msexell, поэтому они не были равны. Как я могу проверить тип файла mimetype для расширений, чтобы избежать переименования? Предоставляются только предоставленные списки расширений, поэтому кто-то может переименовать его и загрузить. Как проверить? – user4271704
ну, я думаю, ты дал мне ключ. Я использовал finfo :: buffer так ненадежно, я изменил его на file_open с физическим файлом, и теперь он возвращает application/vnd.ms-excel вместо октетного потока, как и ожидалось. но теперь другая проблема: как проверить, разрешен ли это файл, как я переименовал имя файла в .txt для загрузки трюка? Должен ли я использовать array_exists для передачи этого типа, чтобы получить ключ массива как .xsl, чтобы увидеть, что это запрещено? – user4271704