Загрузка файла PHP: подтверждение на mime или расширение?
Когда я пытаюсь обработать загрузку файла, должен ли я запускать проверку на основе типа файла MIME или расширения файла?
Каковы достоинства и недостатки этих двух способов проверки файлов?
И, Любые другие проблемы безопасности, о которых я должен беспокоиться?
В эти дни я полагался на MIME-тип, но ответ с большинством голосов в этом сообщении
Проблемы с загрузкой файлов в PHP:
Никогда не полагайтесь на тип MIME, отправленный браузером!
Ответы
Ответ 1
Хорошо, поэтому всем гениальным существам здесь что-то рассказывало о "ВИНТОВЫХ РАСШИРЕНИЯХ, ПРОВЕРЬТЕ MIME! FILEINFO RLZ!", я подготовил несколько уроков:
В заключение вы должны НИКОГДА НИКОГДА НИКОГДА не полагаться на тип MIME. Ваш веб-сервер не заботится о типе MIME, он определяет, что делать с помощью EXTENSION, в конечном итоге downvoted @Col. Ответ на шрапнель на самом деле прав. Любая информация, предоставленная вам чем-то, проверяющим MIME, абсолютно не имеет отношения к вашему веб-серверу, когда дело доходит до выполнения.
РЕДАКТИРОВАТЬ: не-как-необычный код-как-вы-хотите-он-быть, который открывает сайт для этого типа атаки:
<?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!';
}
Ответ 2
Нет для точного определения типа файла. Причины -
* Расширение - пользователь может легко изменить расширение, просто переименовав файл.
* Тип Mime. Чтобы изменить тип mime, некоторое дополнение/расширение может сделать это, поскольку оно поступает с клиентской стороны (поэтому его можно изменить перед отправкой на сервер), не генерируемый сервером.
Теперь для проверки ответ на вопрос зависит от того, почему вы хотите проверить тип файла.
В большинстве случаев нам нужно убедиться, что загруженный файл не должен выполняться. По этой причине вы должны быть уверены в том, как ваш сервер обрабатывает/выполняет файлы.
- Если ваш сервер проверяет расширения для проверки, вам также необходимо проверить, что вы не храните файл с расширением, которое может быть выполнено.
- Если ваш сервер использует mime-типы, остерегайтесь того факта, что mime-тип, отправленный клиентом, и тип mime, используемые сервером для одного и того же файла, могут быть разными. Поэтому используйте ту же логику, что и ваш сервер, чтобы узнать тип mime.
Ответ 3
Mime-type не является надежным источником, потому что он отправляет из браузера (также каждый может создать HTTP-запрос вручную). PHP не проверяет эквивалентность расширения и типа мины (http://ru.php.net/manual/en/features.file-upload.post-method.php). Вы можете указать HTTP-запрос с именем файла image.php и mime-type "image/gif".
Используйте всегда проверку по расширению, если хотите сохранить загруженный файл на жесткий диск и предоставить публичный доступ к этому файлу позже.
Ответ 4
Чтобы точно определить, что было загружено, вы не проверяете расширение файла или тип 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