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

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

Это оригинальный script я использовал 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!");
    }
}

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

Ответ 1

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

Совет айсберга!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ETA для комментариев:

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

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

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

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

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

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

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

Ответ 10

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

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