Подтвердить что ты не робот

Как я могу сказать, если кто-то подделывает файл? (PHP)

Я программирую что-то, что позволяет пользователям хранить документы и изображения на веб-сервере, которые будут храниться и извлекаться позже. Когда пользователи загружают файлы на мой сервер, PHP сообщает мне, какой тип файла он основан на расширении. Тем не менее, я боюсь, что пользователи могут переименовать zip файл как somezipfile.png и сохранить его, тем самым сохраняя zip файл на моем сервере. Есть ли разумный способ открыть загруженный файл и "проверить", чтобы убедиться, что он действительно относится к указанному типу файлов?

4b9b3361

Ответ 1

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

Ответ 2

Посмотрите FileInfo Расширение PECL для PHP, которое может выполнять MIME-макеты для вас.

Ответ 3

Сорт. Большинство типов файлов имеют некоторые байты, зарезервированные для их маркировки, поэтому вам не нужно полагаться на расширение. Сайт http://wotsit.org - отличный ресурс для поиска этого для определенного типа.

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

Для PNG (http://www.w3.org/TR/PNG-Rationale.html)

Первые восемь байтов файла PNG всегда содержат следующие значения:

(десятичный) 137 80 78 71 13 10 26 10

(шестнадцатеричный) 89 50 4e 47 0d 0a 1a 0a

(обозначение ASCII C)\211 P N G\r\n\032\n

Ответ 4

Многие типы файлов имеют " магические числа" в начале файла для их идентификации. Вы можете прочитать несколько байтов с фронта файл и сравнить их со списком известных магических чисел.

Ответ 5

Если вы имеете дело только с изображениями, то getimagesize() должен отличать действительное изображение от поддельного.

$ php -r 'var_dump(getimagesize("b&n.jpg"));'
array(7) {
  [0]=>
  int(200)
  [1]=>
  int(200)
  [2]=>
  int(2)
  [3]=>
  string(24) "width="200" height="200""
  ["bits"]=>
  int(8)
  ["channels"]=>
  int(3)
  ["mime"]=>
  string(10) "image/jpeg"
}

$ php -r 'var_dump(getimagesize("/etc/passwd"));'
bool(false)

Значение false из getimagesize не является изображением.

Ответ 6

В unix-системе захват вывода из команды "файл" должен содержать соответствующую информацию.

Ответ 7

Для получения точного ответа о том, как вы могли бы быстро это сделать в PHP, проверьте этот вопрос: Как найти тип файла mime с php?

Ответ 8

В качестве побочной заметки я столкнулся с аналогичной проблемой, когда мне приходилось выполнять собственные проверки типов. Интерфейс интерфейса для моего приложения был выполнен во флэш-памяти. Файлы передавались через flash на php script. Когда я пытался выполнить проверку типа MIME с использованием php, возвращаемый тип всегда был application/octetstream, потому что он исходил от флэш-памяти.

Мне пришлось реализовать парадигму типа магических чисел. Я просто создал xml файл, в котором был сохранен тип файла, а также некоторые шаблоны определения, найденные в начале файла. После того, как файл достиг сервера, я сделал некоторый шаблон, соответствующий файлу xml, а затем принял или отклонил файл. Я не заметил никакого реального снижения производительности, которого я ожидал.

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

Ответ 9

Помимо идентификации типа файла, вы можете захотеть следить за файлами с другими встроенными или добавленными к ним файлами. Это, к сожалению, потребует более глубокого анализа содержимого файла, чем просто использование "магических чисел".

Например, http://quantumrook.wordpress.com/2007/06/06/hide-a-rar-file-in-a-jpg-file/ (этот конкретный тип скрытия данных можно легко обойти, загрузив и сохранив в новый файл фактические данные изображения.. другим будет сложнее.)