Уязвимости и опасности загрузки файлов
Уязвимость загрузки файла означает, что сетевой злоумышленник загружает исполняемый файл на сервер.Если разработчик не проверит и не обработает файл должным образом, весьма вероятно, что программа выполнит загруженный файл, что приведет к уязвимости системы безопасности. Большинство веб-сайтов имеют функцию загрузки файлов, таких как аватары, изображения, видео и т. д. Если логика этой части не обрабатывается должным образом, легко вызвать уязвимости сервера. Эта уязвимость чаще встречается в программах, характеризующихся URL-адресами имен файлов. Ну да, это лучший язык в мире, PHP. Например, если пользователь загружает PHP-файл и получает адрес соответствующего файла, он может быть выполнен, вред очевиден. Итак, нет ли уязвимости при загрузке файлов в Node.js? Ответ определенно нет. Помимо исполняемых файлов, существует несколько потенциальных проблем, описанных ниже.
имя файла
В загружаемом пользователем файле есть две вещи, которые часто используются программой: одна — это сам файл, а другая — имя файла. Если имя файла используется для чтения или хранения содержимого, вы должны быть осторожны. Злоумышленник, скорее всего, создаст../../../attack.jpg
Если программа не обратит внимания на его прямое использование, то с большой долей вероятности перезапишет ключевые файлы сервера и вызовет сбой программы, а еще более вероятно, что напрямую/etc/passwd
Перезапишите пароль, указанный злоумышленником, чтобы взломать сервер.
Некоторые студенты могут сказать,/
и другие символы являются недопустимыми символами в именах файлов, и пользователи не могут определять такие имена. Вы правы, но нам нужно знать, что мы не взаимодействуем напрямую с файлами пользователя, а получаем файлы пользователя через HTTP-запросы. В запросах на загрузку формы HTTP имя файла сохраняется в виде строки. Пока это допустимый формат HTTP-запроса, злоумышленник может создать любой контент в запросе для отправки на сервер.
POST /upload HTTP/1.1
Host: test.com
Connection: keep-alive
Content-Length: 4237161
Accept: */*
Origin: http://test.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9pQqgBGwpDfftP8l
Referer: http://test.com
Accept-Encoding: gzip, deflate
Accept-Language: en,zh-CN;q=0.9,zh;q=0.8,zh-TW;q=0.7,da;q=0.6
------WebKitFormBoundary9pQqgBGwpDfftP8l
Content-Disposition: form-data; name="file"; filename="../../attack.jpg"
Content-Type: image/jpeg
------WebKitFormBoundary9pQqgBGwpDfftP8l--
HTML и SVG
Хотя уязвимость Node.js к исполняемым программам сервера загрузки файлов не так высока, как у PHP, в дополнение к исполняемым программам на стороне сервера у нас также есть исполняемые программы на стороне клиента, поэтому нам все еще нужно быть готовым. Предполагается, что пользователи могут загружать файлы в любом формате, и если злоумышленник загружает HTML-файлы, он может сотрудничать с CSRF-атаками для дальнейшего создания XSS-атак.
Если вы являетесь интерфейсом для загрузки изображений, также возникает проблема, если вы ограничиваете только формат HTML, потому что в формате SVG существует особый вид изображений. SVG — это формат векторной графики, который использует XML для описания изображений, внутри которых мы можем вставлять<html>
, <style>
, <script>
и т. д. теги DOM. Неожиданные эффекты также могут возникнуть, если содержимое файла в SVG не фильтруется.
<svg viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<script>alert(111)</script>
<rect x="25" y="25" width="50" height="50" />
</svg>
мягкая цепь
Мы знаем, что мягкая цепочка в операционной системе по сути является файлом, но этот файл не содержит фактического содержимого, он содержит путь к другому файлу. Может быть любым файлом или каталогом и может связывать файлы из разных файловых систем. Если злоумышленник загружает файл soft chain, описание soft chain соответствует/etc/passwd
В этом случае программа-эксплойт злоумышленника может напрямую прочитать содержимое файлов ключей сервера, в результате чего сервер будет скомпрометирован.
серверный диск
Помимо проблемы с самим файлом, есть еще одна ситуация, которую нам необходимо рассмотреть, — это обработка после загрузки файла. Если мы будем хранить загруженные пользователями файлы локально, не ограничивая частоту загрузки пользователями, это может быть использовано злоумышленниками. Злоумышленники будут часто загружать файлы, в результате чего диск сервера будет занимать 100%, после того как сервер будет перегружен, он не сможет выполнять другие задачи программы, что приведет к простою сервера.
способ защиты
Для вышеупомянутых возможных сценариев уязвимости нам необходимо сделать следующее:
- При использовании имени файла, переданного пользователем, старайтесь максимально фильтровать белый список.Если возможно, старайтесь не использовать имя файла, переданное пользователем, чтобы предотвратить лазейки в системе безопасности, вызванные именем файла.
- Проверьте формат самого содержимого файла, занеся его в черный или белый список, но метод внесения в белый список будет более безопасным. Формат файла не может просто определять суффикс файла или форму, которая прикрепляется при загрузке формы.
Content-Type
поля, поскольку эти два загружаются пользователем, являются конструируемыми. Лучше всего прочитать магический номер в заголовке файла и сотрудничать с белым списком, чтобы избежать этой проблемы. Более известный модуль, использующий магические числа для определения типа файла, называетсяRes или Fox на GitHub.com/sin…, рекомендуется использовать его напрямую. - Если пользователям разрешено загружать
.svg
Если вы форматируете изображение, вам необходимо выполнить анализ HTML для содержимого SVG и отфильтровать<script>
,<foreignObject>
и другие связанные теги. Конечно, лучше всего использовать белый список. Вот более развернутоБелый список допустимых тегов SVG.
Напоминаем, что если сжатый пакет, загруженный пользователем, распаковывается программой, то не только сам сжатый пакет должен быть проверен по вышеуказанным правилам, но и все содержимое после распаковки должно быть проверено по той же логике . В то же время, для ситуации, когда диск сервера разрывается, рекомендуется ограничить частоту загрузки пользователя, чтобы снизить риск, и в то же время увеличить сигнал тревоги мониторинга диска, чтобы обратить внимание на состояние онлайн-сервера в в реальном времени. Если нет необходимости хранить локально, вы также можете использовать службу внешнего хранилища, чтобы снизить риск сервера.