Остановить загрузку вредоносных файлов PHP через формы

У меня есть форма загрузки, созданная в php на моем веб-сайте, где люди могут загружать zip-файл. Затем zip-файл извлекается, и все расположения файлов добавляются в базу данных. Форма загрузки предназначена для того, чтобы люди могли загружать только фотографии, очевидно, с файлами, находящимися в папке zip, я не могу проверить, какие файлы загружаются до тех пор, пока файл не будет извлечен. Мне нужен фрагмент кода, который удалит все файлы, которые не являются форматами изображений (.png, .jpeg и т. Д.). Я действительно беспокоюсь о том, что люди могут загружать вредоносные php-файлы, большой риск для безопасности! Мне также нужно знать людей, которые изменяют расширения файлов php, пытаясь обойти эту функцию безопасности.

Это оригинальный сценарий, который я использовал http://net.tutsplus.com/videos/screencasts/how-to-open-zip-files-with-php/

Это код, который фактически извлекает .zip-файл:

function openZip($file_to_open) { global $target; $zip = new ZipArchive(); $x = $zip->open($file_to_open); if($x === true) { $zip->extractTo($target); $zip->close(); unlink($file_to_open); } else { die("There was a problem. Please try again!"); } } 

Спасибо, Бен.

Im действительно беспокоился о том, что люди могут загружать вредоносные файлы php, большой риск для безопасности!

Верхушка айсберга!

Мне также нужно знать людей, которые изменяют расширения файлов php, пытаясь обойти эту функцию безопасности.

Обычно изменение расширений останавливает PHP от интерпретации этих файлов как скриптов. Но это не единственная проблема. Есть больше вещей, чем «… php», которые могут повредить серверную сторону; «.htaccess» и файлы с набором бит X являются очевидными, но далеко не все, о чем вам нужно беспокоиться. Даже игнорируя серверные вещи, существует огромная проблема на стороне клиента.

Например, если кто-то может загрузить файл «.html», он может включить в него тег <script>, который захватывает сеанс стороннего пользователя и удаляет все их загруженные файлы или изменяет их пароль или что-то в этом роде. Это классическая атака с использованием межсайтового скриптинга (XSS).

Кроме того, благодаря «обнюхивающим» поведением некоторых браузеров (в первую очередь IE), файл, загружаемый как «.gif», может содержать вредоносный HTML, такой как этот. Если IE видит, что телители, как (но не ограничиваясь ими) «<html>», находятся рядом с началом файла, он может игнорировать поданный «Content-Type» и отображать как HTML, что приводит к XSS.

Кроме того, можно создать файл, который является как действительным изображением, которое будет принимать ваш парсер изображений, так и содержит встроенный HTML. Существуют различные возможные результаты в зависимости от точной версии браузера пользователя и точного формата файла изображения (в частности, в JPEG-файлах имеется очень переменный набор возможных форматов заголовков). В IE8 есть смягчения , но на данный момент это бесполезно, и вам нужно задаться вопросом, почему они не могут просто перестать делать контент-обнюхивание, вы идиоты MS вместо того, чтобы обременять нас шонками нестандартными расширениями HTTP-заголовков, которые должны иметь Просто работал в первую очередь.

Я снова нападаю. Я остановлюсь. Тактика для надежного обслуживания изображений, поставляемых пользователем:

1: Никогда не храните файл в файловой системе вашего сервера, используя имя файла, взятое из пользовательского ввода. Это предотвращает ошибки, а также атаки: разные файловые системы имеют разные правила о том, какие символы допустимы, где в имени файла, и это намного сложнее, чем вы могли бы подумать о «дезинфекции» имен файлов.

Даже если вы взяли что-то очень ограничительное, как «только буквы ASCII», вам все равно придется беспокоиться о слишком длинных, слишком коротких и зарезервированных именах: попробуйте сохранить файл с таким же безобидным именем, как «com.txt», на Сервер Windows и посмотрите, как ваше приложение идет вниз. Думаете, вы знаете все странные недостатки названий путей для каждой файловой системы, на которой может работать ваше приложение? Уверенная в себе?

Вместо этого сохраните сведения о файле (например, имя и тип носителя) в базе данных и используйте первичный ключ в качестве имени в своем файле (например, «74293.dat»). Затем вам нужен способ обслуживать их с различными кажущимися именами файлов, такими как скрипт загрузчика, выплевывающий файл, сценарий загрузчика, выполняющий внутреннюю переадресацию веб-сервера, или переписывание URL.

2: Будьте очень осторожны, используя ZipArchive. В extractTo были обнаружены уязвимости в том же роде, которые затронули самые наивные экстракторы ZIP на основе пути. Кроме того, вы открываете атаку из почтовых бомб . Лучше избегать любой опасности неправильных имен файлов, перейдя через каждую запись файла в архиве (например, используя zip_read / zip_entry_ * ) и проверяя его данные, прежде чем вручную распаковать его поток в файл с известными именами и флагами режима, которые вы созданный без помощи архива. Игнорируйте пути папки внутри ZIP.

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

4: Если вы можете уйти с обслуживанием всех своих изображений в качестве загрузок (т. Е. Используя «Content-Disposition: attachment» в сценарии загрузчика), вы, вероятно, будете в безопасности. Но это может быть слишком большим количеством неудобств для пользователей. Это может работать в тандеме с (3), хотя, обслуживая меньшие, обработанные изображения встроенные и имеющие оригинальные изображения более высокого качества, доступные только для загрузки.

5: Если вы должны подавать неизмененные изображения в линию, вы можете удалить риск межсайтового скриптинга, отправив их из другого домена. Например, используйте «images.example.com» для ненадежных изображений и «www.example.com» для основного сайта, который содержит всю логику. Убедитесь, что файлы cookie ограничены только правильным виртуальным хостом и что виртуальные хосты настроены таким образом, что они не могут ответить ни на что, кроме своих собственных имен (см. Также: DNS-повторные атаки). Это то, что делают многие службы электронной почты.

Таким образом, пользовательский медиа-контент является проблемой.

В резюме резюме, AAAARRRRRRRGGGGHHH.

Комментарий ETA:

наверху вы упомянули о «файлах с X бит-множеством», что вы подразумеваете под этим?

Я не могу говорить для ZipArchive.extractTo() поскольку я его не тестировал, но многие экстракторы, когда их просят выгрузить файлы из архива, воссоздают [некоторые] флаги режима файла Unix, связанные с каждым файлом (если архив был создан на Unix и так на самом деле имеет флаги режима). Это может вызвать проблемы с разрешениями, если, скажем, отсутствует разрешение на чтение владельца. Но это также может быть проблемой безопасности, если ваш сервер включен с поддержкой CGI: бит X может разрешить интерпретацию файла как скрипта и передать его любому интерпретатору скриптов, указанному в хэш-бэнге в первой строке.

Я думал, что .htaccess должен быть в основном корневом каталоге, разве это не так?

Зависит от того, как настроен Apache, в частности директива AllowOverride. Общим для хостов общего назначения является AllowOverride в любом каталоге.

что произойдет, если кто-то еще загрузит файл, например ../var/www/wr_dir/evil.php?

Я бы ожидал, что ведущий «..» будет отброшен, вот что сделали другие инструменты, которые пострадали от одной и той же уязвимости.

Но я до сих пор не доверяю extractTo() от враждебного ввода, слишком много странных небольших файлов / файлов дерева каталогов, которые могут пойти не так, особенно если вы ожидаете когда-либо запускаться на серверах Windows. zip_read() дает вам гораздо больший контроль над процессом деархивирования, а значит, и злоумышленника гораздо меньше.

Сначала вы должны запретить каждый файл, который не имеет надлежащего расширения файла изображения. И после этого вы можете использовать функцию getimagesize чтобы проверить, являются ли файлы обычными файлами изображений.

Но, кроме того, вы должны знать, что некоторые форматы изображений допускают комментарии и другую метаинформацию. Это может быть использовано для вредоносного кода, такого как JavaScript, который некоторые браузеры будут выполнять при определенных обстоятельствах (см. Рискованный MIME-обнюхивание в Internet Explorer ).

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

Я не вижу риска переименования php-файлов в вашу БД … Пока вы не оцениваете их как файлы PHP (или вообще, если на то пошло), они не могут нанести слишком большого вреда, и так как нет расширения .php, php-движок не тронет их.

Я думаю, вы также можете искать файлы для <?php

Также : допустите худшее о файлах, загруженных на ваш компьютер. Переименовал папку, в которую вы сохраняете «вирусы», и относитесь к ней соответствующим образом. Не делайте это общедоступным, не предоставляйте разрешения на запуск файлов (особенно пользователь php) и т. Д.

Вы также можете рассмотреть возможность обнаружения типа mime со следующей библиотекой:

http://ca.php.net/manual/en/ref.fileinfo.php

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

offtopic: не лучше ли пользователю выбирать пару изображений вместо загрузки zip-файла. Лучше для людей, которые не знают, что такое zip (да, они существуют)

Если вы установите php только для разбора файлов, заканчивающихся на .php, вы можете просто переименовать файл из somename.php в somename.php.jpeg, и вы в безопасности.

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

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

Beaware этого Прохождение вредоносного PHP Через getimagesize ()

внедрить PHP через функции изображения, которые пытаются обеспечить безопасное отображение изображений с помощью функции getimagesize ()

подробнее здесь http://ha.ckers.org/blog/20070604/passing-malicious-php-through-getimagesize/

Лучше для вашего логотипа пользователя использовать gravatar, как здесь используется Stackoverflow;)

Используйте функцию getimagesize. Полная процедура: – 1.) Извлечь расширение изображения / загруженного файла, а затем сравнить расширение с разрешенным расширением. 2.) Теперь создайте случайную строку для переименования загруженного файла. Лучшая идея – md5(session_id().microtime()) . Его нельзя дублировать, и если ваш сервер очень быстрый и может обрабатывать меньше, чем микросекунду, чем использовать увеличиваемую переменную и добавлять их со строкой. теперь переместите этот файл.

Совет. Отключите обработку файлов PHP в каталоге загрузки, он всегда будет препятствовать любой атаке на стороне сервера и, если возможно, добавит ваш htaccess в корневой каталог или в файл конфигурации httpd и отключит файлы htaccess оттуда, теперь он решит ваши максимальные проблемы