Сделать загрузку файла ASP.Net безопасным

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

Из того, что я могу сказать, лучше всего проверить, что расширение файла или тип MIME такого типа и проверить его на "магические числа", чтобы убедиться, что расширение не было изменено. Я не слишком обеспокоен тем, как это сделать, но хочу знать, действительно ли этого достаточно.

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

Загрузка файла blueimp jQuery http://blueimp.github.io/jQuery-File-Upload/

и cutesoft ajaxuploader http://ajaxuploader.com/Demo/

Но, похоже, для blueimp требуется проверка пользовательского сервера (я предполагаю, что просто jQuery он просто обрабатывает проверку на стороне клиента), а .net проверяет тип MIME на соответствие расширению, но я думал, что тип MIME следует за расширением в любом случае.

Итак,

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

Я уверен, что ничто не является пуленепробиваемым на 100%, но загрузка файлов довольно распространенная, и я предполагаю, что большинство реализаций "достаточно безопасны" - но как!?

Если это актуально, вот мой базовый код до сих пор

<p>Please attach your CV here</p>
<asp:FileUpload ID="fileUploader" runat="server" />

и на submit

MailMessage message = new MailMessage();
if (fileUploader.HasFile)
{
    try
    {
        if (fileUploader.PostedFile.ContentType == "text")
        {
            // check magic numbers indicate same content type... if(){}

            if (fileUploader.PostedFile.ContentLength < 102400)
            {
                string fileName = System.IO.Path.GetFileName(fileUploader.PostedFile.FileName);
                message.Attachments.Add(new Attachment(fileUploader.PostedFile.InputStream, fileName));
            }
            else
            {
                // show a message saying the file is too large
            }
        }
        else
        { 
           // show a message saying the file is not a text based document
        }
    }
    catch (Exception ex)
    {
        // display ex.Message;
    }
}

Ответы

Ответ 1

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


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

Входы от клиента в нашем случае:

  • имя файла
    • имя
    • расширение
  • содержимое файла

Extension

Мы действительно не заботимся о minetype, это информация для веб-сервера. Мы заботимся о расширении файла, потому что это индикатор для ОС о том, как запускать/читать/открывать файл. Мы должны поддерживать только определенные расширения файлов (что когда-либо может обрабатывать ваш компьютер администратора) нет смысла поддерживать неизвестные типы файлов.

Имя (без расширения)

Имя файла не всегда является ценной информацией. Когда я занимаюсь загрузкой файлов, я обычно переименовываю его (устанавливаю) в id (имя пользователя, метку времени, хэши и т.д.). Если имя важно, всегда проверяйте/обрезаете его, если вы только ожидаете, что буквы или цифры удаляют все остальные символы (я не могу оставить "/", "\", ".", Потому что они могут использоваться для ввода путей).

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

Содержание

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


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

Еще несколько советов, не давайте больше информации клиенту, чем ему нужно... не позволяйте клиенту знать, где хранятся файлы, не позволяйте веб-серверу получать доступ к ним для распространения, если нет нужно. Храните журнал с необычными действиями (слэши в именах файлов, слишком большие файлы, слишком длинные имена, предупреждающие расширения, такие как "sh" "exe", "bat" ) и сообщают администраторам по электронной почте, если что-то странное (хорошо знать, если ваша защита работает).

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

С быстрым поиском google Avast! Для Linux - Руководство по командной строке, я не рекламирую Avast, я просто показываю его как существующий пример.

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


Еще несколько мыслей, JavaScript, запущенный на веб-странице, защищен только для клиентского компьютера (благодаря безопасности браузера). Мы можем использовать его для предотвращения недействительных сообщений на сервере, но это не гарантирует, что такие запросы не будут выполнены, поскольку JavaScript можно обойти/отредактировать.

Итак, все JavaScript-решения предназначены только для первой проверки (как правило, чтобы помочь пользователю правильно исправить ошибки) и правильно установить данные формы.