Проверка загруженных файлов в Django

Приложение Django, которое я работаю, имеет модель Event. Event может иметь связанные фотографии, статические html файлы и файлы PDF.

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

Обратите внимание, что всякий раз, когда вы имеете дело с загруженные файлы, вы должны заплатить внимание к тому, где вы загружаете их и какие типы файлов они есть, чтобы избежать дыр в безопасности. Подтвердить все загруженных файлов, чтобы вы были уверены, что файлы, как вы думаете. Для Например, если вы вслепую позволили кому-то загружать файлы без проверки на в вашей сети серверный корень документа, затем кто-то может загрузить CGI или PHP script и выполните script, посетив его URL на вашем сайте. Не допускайте этого.

Как я могу проверить различные типы файлов? Мне было бы интересно услышать любой опыт общения с такими вещами или ссылки для дальнейшего чтения. У меня есть ощущение, что html файлы могут быть слишком рискованными, и в этом случае я ограничу права доступа для администратора.

Ответ 1

Все ответы сосредоточены на проверке файлов. Это практически невозможно.

Разработчики Django не просят вас проверить, могут ли файлы выполняться как файлы cgi. Они просто говорят вам не помещать их в место, где они будут казнены.

Вы должны поместить все материалы Django в специальный каталог Django. Этот каталог кода Django не должен содержать статический контент. Не помещайте файлы пользователя в исходный репозиторий Django.

Если вы используете Apache2, посмотрите основной учебник cgi: http://httpd.apache.org/docs/2.0/howto/cgi.html

Apache2 может быть настроен для запуска любых файлов в папке ScriptAlias. Не помещайте файлы пользователя в папки /cgi-bin/ или /usr/local/apache2/cgi-bin/.

Apache2 может быть настроен на файлы cgi сервера, в зависимости от настроек AddHandler cgi-script. Не позволяйте пользователям отправлять файлы с расширениями, например .cgi или .pl.

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

Кроме того, SVG может быть небезопасным. У него были ошибки в прошлом. SVG - это XML-документ с javascript, поэтому он может быть вредоносным.

PDF... сложный. Вы можете преобразовать его в изображение (если вам действительно нужно) или предоставить предварительный просмотр изображения (и позволить пользователям загружаться на свой страх и риск), но это было бы болью для людей, пытающихся его использовать.

Рассмотрим белый список файлов, которые в порядке. Вирус, встроенный в файл gif, jpeg или png, будет выглядеть как поврежденный снимок (или не отображается). Если вы хотите быть параноидальным, преобразуйте их все в стандартный формат с помощью PIL (эй, вы также можете проверить размеры). Санированный HTML-код должен быть в порядке (удаление script тегов - это не ракетостроение). Если санитария - это сосание циклов (или вы просто осторожны), вы можете поместить его на отдельный сервер, я думаю.

Ответ 2

Для изображений вы можете просто использовать Python Imaging Library (PIL).

Image.open(filepath)

Если файл не является изображением, будет выбрано исключение. Я новичок в Python/Django, поэтому у кого-то еще может быть лучший способ проверки изображений.

Ответ 3

Первое, что вы хотите сделать с загруженным контентом, - это сохранить его в каталоге, который не доступен напрямую для загрузки. Если ваше приложение существует в ~/www/, рассмотрите возможность размещения ваших данных в '~/data/`.

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

Вы не можете доверять файлу на основе расширения, поэтому используйте что-то вроде Fileinfo. Затем для каждого типа mime создайте валидатор. ImageMagick может проверять файлы изображений. Для повышения безопасности вам может потребоваться запустить антивирусный сканер поверх файлов, таких как pdf и флеш файлы. Для html вы можете рассмотреть ограничение на подмножество тегов.

Я не могу найти эквивалент Python модуля Fileinfo, хотя всегда можно выполнить exec /usr/bin/file -i. Большинство систем, разрешающих загрузку, затем создают имя или идентификатор содержимого. Затем они используют mod_rewrite для анализа URL-адреса и поиска содержимого на диске. Как только содержимое будет найдено, оно вернется к пользователю с помощью файла sendfile или чего-то подобного. Например, до тех пор, пока контент не будет одобрен, возможно, только пользователю, который его загрузил, разрешено его просматривать.

Ответ 4

Это немного специфично для вашей среды размещения, но вот что я делаю:

Слушайте весь загруженный пользователем контент с помощью Nginx вместо apache и обслуживайте его как статический контент (он не будет запускать ни один из php или cgi, даже если пользователи загружают его)

Ответ 5

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

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

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

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

Ответ 6

вы можете проверить html файлы с помощью BeautifulSoup