Я программирую что-то, что позволяет пользователям хранить документы и изображения на веб-сервере, которые будут храниться и извлекаться позже. Когда пользователи загружают файлы на мой сервер, PHP сообщает мне, какой тип файла он основан на расширении. Тем не менее, я боюсь, что пользователи могут переименовать zip-файл как somezipfile.png и сохранить его, тем самым сохраняя zip-файл на моем сервере. Есть ли разумный способ открыть загруженный файл и «проверить», чтобы узнать, действительно ли он относится к указанному типу файлов?Как я могу сказать, если кто-то подделывает файл? (PHP)
ответ
Magic number. Если вы можете прочитать первые несколько байтов двоичного файла, вы можете узнать, что это за файл.
Сорт. Большинство типов файлов имеют некоторые байты, зарезервированные для их маркировки, поэтому вам не нужно полагаться на расширение. Сайт 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 PNG \ г \ п \ 032 \ п
Многие типы файлов имеют «magic numbers» в начале файла для их идентификации. Вы можете прочитать несколько байтов с передней части файла и сравнить их со списком известных магических чисел.
В системе unix сбор данных из команды «файл» должен обеспечивать адекватную информацию.
Проверьте расширение FileInfo PECL для PHP, которое может выполнять MIME-магия для вас.
Для точного ответа о том, как вы могли бы быстро сделать это в PHP, проверить этот вопрос: How do I find the mime-type of a file with php?
Если дело только с изображениями, то 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)
Недопустимое значение getimagesize - это не изображение.
В качестве побочного примечания я столкнулся с аналогичной проблемой, когда мне приходилось выполнять проверку своего типа. Интерфейс интерфейса для моего приложения был выполнен во флэш-памяти. Файлы передавались через флэш-скрипт. Когда я пытался выполнить проверку типа MIME с использованием php, возвращаемый тип всегда был application/octetstream, потому что он исходил от флэш-памяти.
Мне пришлось реализовать парадигму типа магических чисел. Я просто создал xml-файл, в котором был сохранен тип файла, а также некоторые шаблоны определения, найденные в начале файла. После того, как файл достиг сервера, я сделал некоторый шаблон, соответствующий файлу xml, а затем принял или отклонил файл. Я не заметил никакого реального снижения производительности, которого я ожидал.
Это только примечание для всех, кто может использовать флешку, как там, переднюю часть и пытается ввести проверку файла после его загрузки.
Помимо идентификации файла, вы можете захотеть следить за файлами с другими встроенными или добавленными к ним файлами. Это, к сожалению, потребует более глубокого анализа содержимого файла, чем просто использование «магических чисел».
Например, http://quantumrook.wordpress.com/2007/06/06/hide-a-rar-file-in-a-jpg-file/ (это особый тип сокрытия данных можно легко обойти путем загрузки и resaving в новый файл фактические данные изображения .. другие будут более трудными.)
- 1. Как я могу сказать, что файл открывается другим приложением?
- 2. Как я могу сказать хвост, если он закончил - чисто?
- 3. Как я могу сказать, требует ли .PFX файл пароля
- 4. Как я могу сказать, если строка содержит подстроку
- 5. , как я могу сказать, если label.text == любой Int
- 6. ява Короче, как я могу сказать, если перенос необходим
- 7. Как я могу сказать, если окно находится в наборе jQuery?
- 8. TransactionScope, как я могу сказать, если Connection был зачислен
- 9. Как я могу сказать в elisp, если Emacs использует X?
- 10. Как легко сказать, если файл зашифрован
- 11. как я могу сказать cgo, чтобы не компилировать файл?
- 12. Как я могу сказать Hexo игнорировать файл при создании сообщений?
- 13. Как я могу сказать SubSonic 2 использовать другой файл .config?
- 14. Как я могу сказать Python прочитать мой текстовый файл?
- 15. Как я могу сказать P4SCC игнорировать файлы?
- 16. Как я могу сказать это в jQuery?
- 17. Как я могу сказать, что PHP-скрипт запускает функцию Javascript?
- 18. Как сказать Git Я обновляю php?
- 19. Как я могу выполнить пакетный файл, если файл можно переименовать?
- 20. Как я могу сказать что-то вроде objdump, если объект-файл был создан с -fPIC?
- 21. Как сказать git Я не перемещал файл?
- 22. Oracle: Могу я сказать программно, если процедура содержит фиксацию?
- 23. Как я могу зашифровать php-файл?
- 24. В финальном блоке, я могу сказать, если исключение было брошено
- 25. Как я могу сказать, заморозил ли докер?
- 26. Как я могу сказать это в sed?
- 27. как я могу использовать, если в PHP
- 28. есть способ, который я могу сказать, если firefox prefetching?
- 29. Я не могу закрыться, так сказать
- 30. Как я могу сказать программно, если имя файла, которое я прошу, существует на веб-сервере?
Магические числа не всегда начало. Я думаю, TGA, например, имеет их в конце. – 2008-10-08 23:02:12
помните, что, полагаясь на эту проверку, злоумышленники могут вставлять магические байты, а затем писать PHP-код в том же файле, чтобы попытаться выполнить код на вашем компьютере. – Jorre 2012-12-04 13:53:03