2009-03-30 3 views
1

Я использую CGI, чтобы позволить пользователю загружать некоторые файлы. Я просто хочу, чтобы просто иметь возможность загружать файлы .txt или .csv. Если пользователь загружает файл с любым другим форматом, я хочу, чтобы вышло сообщение об ошибке.Как я могу ограничить типы файлов в загрузке файлов CGI в Perl?

я увидел, что это можно сделать с помощью JavaScript: http://www.codestore.net/store.nsf/unid/DOMM-4Q8H9E

Но есть лучший способ для достижения этой цели? Есть ли в Perl некоторые функции, которые позволяют это?

ответ

6

Оговорка на сайте, чтобы вы ссылка Важен:

Примечание: Это не совсем несложное, как люди могут легко изменить расширение файла перед загрузкой или сделать некоторые другие фокусы, а в случае вируса «LoveBug».

Если вы действительно хотите сделать это правильно, пусть пользователь загрузить файл, а затем использовать что-то вроде File::MimeInfo::Magic (или file(1), в UNIX утилита ) угадать фактический тип файла. Если вам не нравится файл , удалите его и сообщите об ошибке.

+0

на окружающую среду я даюсь, у них нет магии. Как можно использовать утилиту file (1) в perl? – 2009-03-30 21:20:57

+0

Просто введите волшебный файл с вашим приложением? – jrockway

3

Я просто хочу, чтобы вы могли загружать файлы .txt или .csv.

Звучит просто, не так ли? Это не. А потом некоторые.

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

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

В любом случае нет гарантии, что браузер отправит вам файл с полезным именем вообще, и даже если это произойдет, нет гарантии, что имя будет иметь «.txt» или «.csv» на end, даже если это текст или CSV-файл. (Некоторые платформы просто не используют расширения для ввода текста.)

Хотя вы можете попытаться обнюхать содержимое файла, чтобы посмотреть, какой тип он может быть, это очень ненадежно. Например:

<html>,<body>,</body>,</html> 

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

Теперь вот где это становится действительно противным. Предположим, вы приняли загрузку и сохранили ее как /data/mygoodfilename.txt, и веб-сервер правильно обслуживает ее как текст-текст/тип контента. Как вы думаете, браузер интерпретирует это как? Простой текст? Тебе должно быть повезло.

Проблема в том, что браузеры (в первую очередь IE) не доверяют заголовку Content-Type и вместо этого просматривают содержимое файла, чтобы увидеть, похоже ли оно на что-то еще. Передайте приведенный выше фрагмент как обычный текст, и IE с удовольствием рассмотрит его как HTML.Это может быть огромной проблемой, поскольку HTML может включать в себя клиентские скрипты, которые будут захватывать доступ пользователя к сайту (атака межсайтового скриптинга).

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

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

На данный момент ваши последние отчаянные возможности такие вещи, как:

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

  • , обслуживающий все загруженные пользователем файлы через оболочку CGI, добавляя заголовок Content-Disposition: attachment, чтобы браузеры не пытались их отображать напрямую;

  • только принимает закачки от доверенных пользователей.

+0

Какие браузеры (помимо IE) не поддерживают Content-Type: text/plain header? – cjm

+0

По крайней мере, Firefox и Opera (хотя их обнюхивание менее широкое). WHATWG даже пытаются его стандартизировать: http://www.w3.org/TR/html5/infrastructure.html#content-type-sniffing-0. Как уродливое и удручающее это все. – bobince

2

На unix самый простой способ - сделать предложенный JRockway. Если вы не используете unix, ваши варианты ограничены. Вы можете проверить расширение файла, и вы можете проверить содержимое для проверки. Я предполагаю для вас конкретный случай, что вам нужны только текстовые файлы «* seperated value». Таким образом, один из модулей Text :: CSV :: * может быть полезен при проверке того, какой файл вы запрашиваете.

Безопасность для этой операции - это целый другой воск.

0

попробовать это:

$file_name = "file.txt"; 

$file_cmd = "file \"$file_name"\"; 

$file_type = `$file_cmd`; 

return 0 unless($file_type =~ /(ASCII|text)/i) 
Смежные вопросы