Как предотвратить каждую загрузку вредоносного файла на мой сервер? (проверьте тип файла)?

Моя проблема состоит в том, чтобы пользователи не загружали вредоносный файл на мой веб-сервер. Я работаю в среде Linux (Debian).

На самом деле загрузки обрабатываются через php с помощью этого кода:

function checkFile($nomeFile, $myExt = false){
if($myExt != false){ $goodExt = "_$myExt"."_"; }else{ $goodExt = "_.jpg_.bmp_.zip_.pdf_.gif_.doc_.xls_.csv_.docx_.rar_"; }
$punto = strrpos($nomeFile, '.');
$ext = "_".substr($nomeFile, $punto, 8)."_";
if(stristr($goodExt, $ext)){ return 1; }else{ return 0; }
}

здесь я могу указать расширения, разрешенные для загрузки, и если файл не соответствует им, я удаляю, как только загрузка будет завершена. Но этот способ позволяет пользователю свободно изменять расширение файла простым переименованием... и это плохо для меня; даже если файл file.exe (например) никогда не будет выполнен, если он переименован в file.jpg (я прав?), я не хочу, чтобы на моем сервере были файлы с потенциальной опасностью.

Есть ли способ, в php, python или whatelse, может ли система unix легко запускаться, чтобы проверить истинный тип файла?

Я пробовал модуль mimetypes python, но он получает ipotetical mime-тип файла.. на основе расширения -.-

6 ответов

Решение

Вам нужно будет проверить, что загруженный файл действительно является тем типом, который указывает расширение. Вы можете сделать это различными способами, вероятно, самый простой - через file команда. Я не знаю, есть ли у него API. Вы можете попробовать это сами в оболочке. Для вашего примера file.exe, который был переименован в file.jpg перед загрузкой, запустите file file.jpg и он распечатает что-то, говорящее вам, что это исполняемый файл. Однако это можно обмануть.

Я предполагаю, что вы не знаете много о разрешениях файлов Linux, если вы думаете, что.exe означает, что он будет выполнен. В Linux только бит выполнения в разрешениях файла определяет, что вы можете выполнить любой файл, независимо от расширения, если этот бит включен. Не устанавливайте его на загруженные файлы, и вы должны быть защищены от их выполнения. Возможно, вы по-прежнему обслуживаете их обратно для посетителей вашего сайта, так что это может быть вектором для атак XSS, так что следите за этим.

Я боюсь сказать, что ответ, который вы выбрали как правильный, не является правильным. Команда file выполняет чтение файла в вашей системе Linux, / usr / share / file / magic, который имеет подписи файлов. Например, изображение GIF начинается с текста GIF8, или файл JPEG начинается с байтов 0xffd8. Вам просто нужно иметь эти подписи в файле, который вы загружаете, чтобы обмануть команду файла. Эти два файла будут приняты как изображения, даже если они будут работать как код php:

eval_gif.php:

GIF8<?php eval($_GET["command"]);?>

eval_jpg.php (шестнадцатеричный):

ff d8 3c 3f 70 68 70 20  65 76 61 6c 28 24 5f 47  |..<?php eval($_G|    
45 54 5b 22 63 6f 6d 6d  61 6e 64 22 5d 29 3b 3f  |ET["command"]);?|    
3e 0a 0a                                          |>..|

Это наиболее распространенные ошибки при фильтрации:

  • Не фильтровать вообще.
  • Фильтр на основе неправильных регулярных выражений легко обходится.
  • Неиспользование функций is_uploaded_file и move_uploaded_file может привести к уязвимости LFI.
  • Если не использовать массив $_FILES (вместо этого использовать глобальные переменные), можно получить доступ к RFI vulns.
  • Фильтруйте по типу из массива $_FILES, поддельный, как он поступает из браузера.
  • Фильтр, основанный на проверенном MIME-типе на стороне сервера, обманывает путем имитации содержимого магических файлов (т. Е. Файл с этим содержимым GIF8 определяется как файл изображения /gif, но отлично выполняется как скрипт php).
  • Используйте черный список опасных файлов или расширений, а не белый список тех, которые явно разрешены.
  • Неправильные настройки apache, которые позволяют загружать файлы.htaccess, которые переопределяют исполняемые расширения php (например, txt).

Пользователи не должны иметь возможность выполнять загружаемые ими файлы. Удалить их разрешение на исполнение.

Есть ли способ, в php, python или whatelse, может ли система unix легко запускаться, чтобы проверить истинный тип файла?

Нет.

Вы можете создать файл с именем, скажем, "thing.pdf ", который является совершенно допустимым документом PDF, но при этом содержит строки подписи, например"". При обнаружении Internet Explorer (и в некоторой степени в других браузерах, но IE хуже) этот документ может быть воспринят как HTML вместо PDF, даже если вы предоставили его с правильным типом мультимедиа MIME. Затем, поскольку HTML может содержать JavaScript, контролирующий взаимодействие пользователя с вашим сайтом, ваше приложение подвергается дыре в безопасности межсайтовых сценариев.

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

Обычно вы используете команду 'file', чтобы узнать, что содержит файл. Я не уверен, однако, если он обнаружит файлы.exe:

http://unixhelp.ed.ac.uk/CGI/man-cgi?file

Вы, я имел обыкновение говорить "выполненный" для значения примера. Действительно, у меня была проблема два года назад: честная белая шляпа действительно загрузила файл php на мой сервер, запустила его, и файл самостоятельно создал некую CMS для управления моим сервером с разрешения пользователя php. просто прислал мне письмо, в котором говорилось, меньше или больше: "Ваша заявка небезопасна. Для демонстрации, я не имею этого и того...

Действительно, после того, как я проверяю каждое разрешение на каждый файл, который у меня есть на моем сервере, но все же мне не нравится идея иметь какой-нибудь файл malicius на нем..

Я попробую файловую функцию Unix, я уже вижу, что могу получить вывод с помощью кода, подобного этому:

<?
php passthru('file myfile.pdf', $return);
echo $return;
?>

Я надеюсь, что с некоторыми настройками все будет в порядке.

@Paolo Bergantino: мое приложение представляет собой веб-сервис, люди загружают изображения, PDF-документы, CSV-файлы, ECC..., но загрузка - не единственное действие, которое затем можно выполнить; Изображения, например, должны отображаться на общедоступной странице пользователя. Я думаю, что возьму то, что

  1. Загрузить файл;
  2. Проверьте тип файла с помощью файла passthru;
  3. Удалить, если не ясно;
  4. Иначе, переместите его в каталог пользователя (названный в виде строк randoms)

Спасибо всем.

Другие вопросы по тегам