Как проверить тип файла по его расширению?

1

Я хочу создать сценарий загрузчика, и я хочу определить несколько разрешенных типов файлов для загрузки, чтобы предотвратить трюк, переименовав расширение файла. Я использую этот массив: PHP/Mime Types. Список доступных типов mime? сначала он проверяет, разрешено ли расширение файла (например,.xsl), затем оно использует finfo для получения mimtype для проверки с этим массивом, чтобы увидеть, соответствует ли mimetype расширению.

Я загрузил файл.xsl, finfo извлекает тип файла как application/octet-stream, но этот массив для расширения xsl возвращает application/x-msexcel, поэтому он не будет равен и не будет проверен.

Должен ли я действительно забыть о сопоставлении mimetype с расширителем валидатора имени для скрипта, и я должен просто проверить расширения файлов? или что мне делать?

  • 0
    как вы убедились, что тип файла «application / octet-stream», если вы сделали это в массиве файлов, это ненадежно, его можно легко подделать. Заголовок типа файла "application / octet-stream" отправляется, если ни один не распознан. это не всегда означает, что загруженный файл относится к этому типу. Вы должны проверить загруженный файл, а не массив $ _FILES для mime-типов
  • 0
    Октет-поток возвращается из finfo :: buffer. Затем я получил mimetype расширения xsl из массива, это был x-msexell, поэтому они не были равны. Как я должен проверить mimetype файла по расширениям, чтобы избежать переименования трюк? Разрешены только предоставленные списки расширений, поэтому кто-то может переименовать его и загрузить. Как проверить?
Показать ещё 4 комментария
Теги:
mime-types
mime
file-type

1 ответ

1
Лучший ответ

В основном вы делаете это правильно. Вы никогда не должны полагаться на заголовки типа mime, которые отправляются из формы загрузки, потому что вы можете легко их подделать или ее нет, тогда вы часто будете получать заголовок application/octet-stream.

Поэтому было бы неплохо проверить, соответствует ли расширение файла разрешенному типу mime для этого расширения файла.

Я видел, что вы связали этот список здесь. Это, безусловно, хороший список, но не очень полезный для 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
}
  • 0
    Как насчет файлов без расширения? Как вы запрещаете / разрешаете их загрузку?
  • 0
    Для размера файла надежно ли использовать mb_strlen в $ _FILES? Или следует использовать только размер файла на физическом файле?
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню