Загрузка файла PHP: проверка на основе MIME или расширения? - PullRequest
12 голосов
/ 08 сентября 2011

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

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

И, какие еще вопросы безопасности мне следует беспокоить?

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

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

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

Ответы [ 4 ]

31 голосов
/ 08 сентября 2011

Хорошо, так что для всех гениев здесь что-то вроде «ВИНТОВЫЕ РАСШИРЕНИЯ, ПРОВЕРИТЬ МИМ! FILEINFO RLZ!», Я подготовил несколько обучающих программ:

  1. Загрузите этот pretty php logoЯ нарисовал
  2. Посмотреть.Довольно мило, не правда ли?
  3. Переименуйте его в what_you_like.php
  4. Пропустите его через все ваши удивительные типы пантомимы / любые шашки
  5. Запустите его

В заключение, вы НИКОГДА не должны НИКОГДА полагаться на MIME-тип.Ваш веб-сервер не заботится о типе MIME, он определяет, что делать с помощью EXTENSION , который в конечном итоге был отклонен @ Col.Shrapnel ответ на самом деле правильный.Любая информация, предоставляемая вам чем-то, проверяющим MIME, абсолютно не имеет отношения к вашему веб-серверу, когда дело доходит до исполнения.

РЕДАКТИРОВАТЬ: not-as-uncommon-code-как вы хотите, чтобы открыть сайт для этого типа атаки:

<?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!';
}
1 голос
/ 08 сентября 2011

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

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

1 голос
/ 08 сентября 2011

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

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

0 голосов
/ 08 сентября 2011

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

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

Копирование / вставка из magic.mime, чтобы вы поняли, как это работает в двух словах:

# 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...