Загрузка файла PHP: проверка на основе MIME или расширения?

когда я пытаюсь обработать загрузку файла, должен ли я запускать проверку на основе типа файла MIME или расширения файла?

каковы плюсы и минусы этих 2 способов проверки файлов?

и, любые другие вопросы безопасности должны меня беспокоить?

в эти дни я полагался на тип MIME, но ответ с большинством голосов в этом посте

проблемы с загрузкой файлов в PHP говорит:

никогда не полагайтесь на тип MIME отправлено браузером!

4 ответов


хорошо, так что для всех гениев здесь тявкают что-то о "винт расширения, проверьте МИМ! FILEINFO НА РЛЗ!", Я подготовил учебник:

  1. скачать довольно php логотип я нарисовал
  2. посмотреть его. Неплохо, правда?
  3. переименуйте его в whatever_you_like.в PHP
  4. положите его через все ваши удивительные мим типа / любые шашки
  5. запустить

В заключение, вы никогда не должны никогда когда-нибудь полагайтесь на тип MIME. Веб-сервер не заботится о типе MIME, он определяет, что делать с помощью расширение, в конечном счете downvoted @Col. Shrapnelответ на самом деле правильный. Любая информация, предоставленная вам чем-то проверяющим MIME, - это абсолютно не имеет отношения к вашему веб-серверу, когда дело доходит до выполнения.

EDIT: не-как-необычный-код-как-вы-хотите-это-быть, который открывает веб-сайт для этого тип атаки:

<?php

$mimetype = mime_content_type($_FILES['file']['tmp_name']);
if(in_array($mimetype, array('image/jpeg', 'image/gif', 'image/png'))) {
   move_uploaded_file($_FILES['file']['tmp_name'], '/whatever/something/imagedir/' . $_FILES['file']['name']);
   echo 'OK';

} else {
    echo 'Upload a real image, jerk!';
}

MIME-тип не является надежным источником, потому что он отправляет из браузера (также любой может создать HTTP-запрос вручную). PHP не проверял эквивалентность расширения и типа mine (http://ru.php.net/manual/en/features.file-upload.post-method.php). Вы можете акцентировать HTTP-запрос с именем файла " image.php "и mime-тип "изображение / gif".

используйте always verification by extension, если вы хотите сохранить загруженный файл на HDD и предоставить публичный доступ к этому файлу позже.


None подходит для точного определения типа файла. Причины - * Расширение-пользователь может легко изменить расширение, просто переименовав файл. * Тип Mime-чтобы изменить тип mime, некоторые надстройки / расширения могут сделать это, так как он поступает с клиентской стороны (поэтому может быть изменен перед отправкой на сервер), а не генерируется сервером.

теперь для проверки, ответ на вопрос зависит от того, почему вы хотите проверить тип файла.

большая часть время, которое нам нужно, чтобы убедиться, что загруженный файл не должен быть выполнен. По этой причине вы должны быть уверены в том, как ваш сервер обрабатывает/выполнение файлов. - Если ваш сервер проверяет расширения для проверки, вам также необходимо убедиться, что вы не храните файл с расширением, которое может быть выполнено. -Если ваш сервер использует MIME-типы, остерегайтесь того факта, что MIME-тип, отправленный клиентом, и MIME-тип, используемый сервером для одного и того же файла, могут быть разными. Поэтому используйте ту же логику, что и ваш сервер чтобы узнать тип мима.


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

в среде * nix у вас есть утилита для проверки типа mime данного файла, обычно расположенного в magic.файл mime (/usr/share / magic.mime или что-то подобное, в зависимости от вашей настройки).

Копировать / Вставить из magic.мим Итак, вы видите, как это работает в двух словах:

# Magic data for KMimeMagic (originally for file(1) command)
#
# Note on adding additional MIME types:
#
# [RFC2045,RFC2046] specifies that Content Types, Content Subtypes, Character
# Sets, Access Types, and conversion values for MIME mail will be assigned and
# listed by the IANA.
# http://www.iana.org/assignments/media-types/
#
# Any unregistered file type should be listed with a preceding x-, as in
# application/x-foo (RFC2045 5.1), or a x., as in application/x.foo (RFC4288
# 4.3).  Any non x-prefixed type should be registered with IANA and listed at
# the above address.  Any other behavior is a MIME standards violation!
#
# It is preferred that when a registered MIME type exists, that
# the registered Content-Type and Subtype be used to refer to a file of
# that type, so don't use application/x-zip when application/zip is
# registered.
#
# If an active RFC suggests that a MIME registration for a new type is in
# progress, make a note of it pointing to that RFC.
#
# The format is 4-5 columns:
#    Column #1: byte number to begin checking from, ">" indicates continuation
#    Column #2: type of data to match
#    Column #3: contents of data to match
#    Column #4: MIME type of result
#    Column #5: MIME encoding of result (optional)

Я свяжу вы со ссылкой, которая поможет вам в дальнейшей реализации в PHP (буквально 2 строки кода, как только вы закончите).

Если вы не можете заставить его работать после всего этого, напишите здесь в комментариях, и я предоставлю полный код, необходимый для безопасного обнаружения того, что было загружено.

Fileinfo