«Ширли-мырли» в CRM. Про недостатки в управлении пользовательскими сессиями: неограниченное время жизни, неконтролируемый выпуск токенов, отсутствие механизма отзыва и др.
Конь троянский. Недостатки, связанные с загрузкой файлов и получением доступа к ним (от классической загрузки шелла и хранимой XSS в файле аватарки (SVG) до кейсов с S3 и CDN).
Так и запишем. Чрезмерное и небезопасное логирование. К чему приводит бесконтрольная запись действий пользователя.
CRM — одна из самых важных для бизнеса и в то же время уязвимых систем (да-да, мы не доверяем никому и берем в расчет и внешних, и внутренних нарушителей). При проведении пентестов и анализе исходного кода таких решений мы пытаемся реализовать как можно больше интересных векторов атак, но не забываем и про классические недостатки и дыры в конфигурации.
Может быть, проблемы с защищенностью CRM кроются в отсутствии ИБ-ориентированных компетенций у разработчиков или проектной команды? Абсолютно точно, нет. CRM-системы невероятно сложны и могут иметь множество интеграций и встраиваемых компонентов. Каждый из них может нести «сюрприз» в виде уязвимости, позволяющей скомпрометировать саму систему, часть ее функционала или бизнес-данные. ТОП-3 выявленных нами недостатков при анализе защищенности CRM за последний год — это уязвимости в управлении сессиями, загрузке файлов и логировании.
Ширли-мырли в CRM
Помните фильм «Ширли-мырли»? А теперь представьте, что его действие разворачивается не на экране, а где-то в недрах вашей CRM. Вы не можете понять: как получилось, что у пользователя Кроликова внезапно оказалось пять токенов пользовательской сессии, его активность резко возросла, а отправляемые запросы явно не соответствуют должностным обязанностям? Кроме того, он настойчиво пытается получить доступ к «Спасителю России» — одному из самых критичных для вашего бизнеса компонентов CRM. Знакомо? Надеюсь, что нет.
Это не фарс — мы встречали такие кейсы. Для авторизации пользователей разработчик создавал им новые токены сроком жизни в один год, не отключая при этом выпущенные ранее. Вишенкой на торте оказалась функция logout1, которая просто удаляла активную сессию из хранилища браузера пользователя и не отправляла при этом никаких запросов на сервер. Ну и последний выстрел себе же в ногу: разработчик решил отключить функционал мониторинга активных пользовательских сессий. Бедный Кроликов даже не мог узнать, что его учетная запись уже скомпрометирована.
Другой свежий пример. Во время пентеста сайта заказчика мы выявили подозрительную активность интегрированного плагина, предназначенного для аналитики действий пользователей. В момент открытия страницы сайта, к которой он был привязан, в браузере пользователя выполнялся код на JS. Вроде все хорошо, но результаты выполнения метода document.cookie отправлялись на сервер, принадлежащий компании-разработчику плагина. Проще говоря, данные о сессиях пользователей и администраторов успешно утекали на сторонний ресурс, который в соответствии с пользовательским соглашением ни за что ответственности не несет. К слову, позже мы выявили аналогичную проблему и в других крупных российских компаниях.
1 Logout – функция прекращения действия пользовательской сессии на сервере.
Конь троянский
С управлением пользовательскими сессиями все в целом понятно — проблема перетекает из года в год. А вот с обработкой и хранением файлов ситуация стала заметно лучше. Теперь загрузить PHP Shell через функционал загрузки файлов — это что-то архаичное, такие кейсы встречаются крайне редко. Большинство разработчиков прекрасно понимают, к чему это может привести, и пытаются защитить сервис и внутри, и снаружи. Они используют фильтрацию по расширению и содержимому, применяют кроппинг 2 изображений, а сами файлы хранят в S3-бакетах.
Но если бы эти подходы были панацеей, мы бы о них не рассуждали. Классический пример уязвимости, которую мы до сих пор выявляем примерно в 3–4 из 10 систем, — возможность загрузки SVG-файлов через функционал установки аватаров. Ведь всем нравится, когда у пользователей есть аватарки, и большинство CRM-систем предоставляют возможности для их загрузки.
Особенность SVG-файлов — их универсальность. Они могут запросто включать код на JS, который будет выполняться в браузере пользователя. Это отличный вектор для реализации XSS и фишинговых атак. Если разработчик знает особенности этого формата, он никогда не допустит, чтобы у пользователя была возможность загружать подобные файлы на сервер. Особенно учитывая, что настоящие картинки для аватаров никогда не создаются и не обрабатываются в SVG.
Но так ли опасна загрузка файлов, если мы сразу помещаем их, к примеру, в S3-хранилище? К сожалению, да. При работе с хранилищами мы встречаем много интересных кейсов: от некорректной настройки ACL на доступ к бакету и до утечек ключей и реализации тех же XSS. Безопасность не бывает точечной, и полумерами здесь не обойтись. Если XSS не сработает при получении файла из бакета (он будет загружен без открытия в браузере), то как быть с интерфейсом администратора в бакете? Особенно, если в домене настроены CSP-политики с указанием wildcard, а адрес бакета является одним из поддоменов.
Встречались и совсем экзотические кейсы. Например, когда разработчики передавали ключи от общего хранилища и формировали подпись непосредственно в браузере. Стоит ли говорить, что будет, если один из пользователей хранилища окажется злоумышленником? Очевидно, оно будет скомпрометировано.
Так и запишем
А что, если мы хотим реагировать на подозрительную деятельность пользователей или собирать как можно больше данных для отладки на уровне самой CRM? Это хорошо, но важно не переусердствовать. За примерами далеко ходить не надо. Можно вспомнить отгремевшую в прошлом году уязвимость Log4Shell в библиотеке log4j2 (CVE-2021-44228), получившую по CVSS 10 баллов из 10 возможных. Она связана с недостатками в обработке событий журналов Java-приложений. Суровый Enterprise любит Java, а Java любит инъекции в JNDI-интерфейс. Отметим, что в приложениях российских вендоров мы тоже выявляли эту уязвимость.
Возвращаясь к вопросу о необходимости логирования всего и вся. Здесь есть важный момент: журналирование действий пользователя в системе и весь пользовательский ввод должны заранее обрабатываться с одинаковыми требованиями. Предварительная санитизация нужна всему, что разработчик ожидает получить от пользователя, включая заголовки самих HTTP-запросов.
Итак, мы выяснили, что прежде чем сформировать массив данных о действиях пользователя, их нужно обработать. А что потом? Держать их в оперативной памяти? Записывать на диск? У этих, казалось бы, не очень важных вопросов могут быть вполне серьезные последствия. Например, в одной CRM мы выявили факт хранения логов в оперативной памяти без записи на диск. Нужны ли логи, которые пропадут после падения приложения или перегрузки виртуальной машины — вопрос к разработчику. Но даже если хранить данные в дисковой памяти, нужно помнить: она тоже может рано или поздно закончиться, что приведет к недоступности приложения (DoS).
Наша практика тестирования кастомных CRM показывает, что проблемы с логированием занимают довольно существенный пласт от общего числа уязвимостей и несут множество векторов для развития атак. Так, среди выявляемых нами проблем встречается «оседание» в логах ценной информации, доступ к которой в самой CRM строго ограничен. Например, токены доступа пользовательских сессий могут попадать в журнал приложения, если они передаются в URL-параметрах запросов пользователей. В этой ситуации одним из векторов атаки может стать компрометация журналов приложения. В случае интеграции со сторонними ресурсами они и вовсе будут утекать через заголовки Referer-запросов браузера.
На наш взгляд, главным критерием при определении глубины логирования приложения должен быть фактор достаточности. Разработчик должен писать в журнал не больше, чем требуется для отладки и нужно с точки зрения ИБ. Для всего остального есть отладочные режимы работы приложения и тестовый контур.
2 Кроппинг – изменение размера изображения
Экспертный комментарий
Ежегодно центр информационной безопасности «Инфосистемы Джет» реализует более 50 проектов по тестированию на проникновение. Среди них процент проектов, где требуется проверить конкретно CRM, невелик. В большинстве случаев с CRM мы сталкиваемся в рамках комплексных проектов для оценки общего уровня защищённости компаний от взломов, в частности, при проведении пентестов внешнего периметра и корпоративной сети. «Коробочные» решения, как правило, имеют более высокий уровень защиты, нежели системы собственной разработки. Это объясняется выстроенными процессами разработки, более тщательным тестированием, широким применением вендорских продуктов, что позволяет производителям получать обратную связь как от компаний-заказчиков, так и от ИБ-экспертов. Однако мы находим уязвимости в системах обоих типов. Чаще всего это небезопасные функции (позволяющие, к примеру, загрузить вредоносный скрипт или файл), «зашитые» в код пароли, ошибки при разработке. Нередко в «предрасположенности» CRM к атакам виноваты сами пользователи, т.к. не меняют установленные по умолчанию пароли или используют слабые, легко поддающиеся подбору. Например, доступ к одной из CRM мы получили, использовав для входа стандартные логин и пароль, прописанные в эксплуатационной документации, находившейся в открытом доступе. Таким образом, для защиты CRM, как и любого другого ценного актива, должен применяться комплексный подход, объединяющий технические и организационные меры.
Николай Антипов
Руководитель департамента консалтинга центра информационной безопасности компании «Инфосистемы Джет»