
Ответственное раскрытие неисправленной уязвимости в FluentCRM от WPManageNinja
Обновление от 2023-06-12: Сниппет больше не нужен. WPManageNinja исправили уязвимость через два часа после публичного раскрытия (через 93 дня после сообщения).
Обновление от 2024-01-27: Связанная проблема с бессрочными хэш-значениями теперь полностью решена.
Кратко: Злоумышленники могут просматривать и редактировать данные контактов в FluentCRM. WPManageNinja не исправили уязвимость в течение 90-дневного срока ответственного раскрытия. Я предоставляю сниппет для смягчения уязвимости в ожидании официального патча.
Сегодня я публикую информацию об уязвимости, которую я обнаружил в популярном плагине WordPress FluentCRM от WPManageNinja. Уязвимость, CVE-2023-1430, вызвана недостаточным использованием хэша адреса электронной почты в качестве контроля авторизации в FluentCRM. Я ответственно раскрыл уязвимость в соответствии с политикой раскрытия уязвимостей Google Zero. WPManageNinja не предоставили патч в течение 90-дневного окна и не запросили продления срока.
В этом отчете под контактом понимается объект контакта FluentCRM, а под пользователем — объект пользователя WordPress. Контакт может быть связан с пользователем, но это не обязательно. Подробности эксплуатации уязвимости не раскрываются до появления официального патча. Специалисты по безопасности могут связаться со мной для получения полного отчета ([email protected]).
На сайтах, использующих FluentCRM, злоумышленник может просматривать и редактировать имя, адрес электронной почты и настройки списков контакта, зная его адрес электронной почты. Поскольку имя контакта часто включается в рассылки через теги слияния, злоумышленник может заменить имя контакта нецензурной лексикой, в результате чего владелец сайта будет отправлять вульгарные письма. Если администратор сайта включил шорткод FluentCRM для управления предпочтениями и добавил его на публичную веб-страницу, злоумышленник может просматривать и редактировать все раскрываемые личные данные, такие как обращение, номер телефона, дата рождения и адрес (в зависимости от конфигурации FluentCRM).
FluentCRM установлен на более чем 30 000 сайтов. Администраторы сайтов с FluentCRM могут предотвратить эксплуатацию уязвимости, добавив мой сниппет для смягчения в файл functions.php дочерней темы.
Сниппет не исправляет уязвимость. Он заменяет уязвимый контент на странице отписки (unsubscribe.php) и странице управления предпочтениями (manage_subscription.php) FluentCRM на сообщение об ошибке, предлагающее контакту связаться по электронной почте. Адрес электронной почты в сообщении об ошибке — это адрес администратора сайта (его можно изменить в сниппете). Сниппет также гарантирует, что неавторизованные посетители не смогут отобразить уязвимый шорткод FluentCRM для управления предпочтениями (fluentcrm_pref). Вместо этого неавторизованный посетитель увидит сообщение об ошибке с предложением войти в систему. Все строки переводимы с помощью прилагаемого POT-файла.
Я рекомендую владельцам сайтов реализовать либо предлагаемое мной смягчение, либо собственное аналогичное. Владельцам сайтов также следует проверить целостность данных контактов FluentCRM и, если возможно, проверить свои журналы на предмет возможных утечек данных. Проверка журналов особенно важна для следующих сайтов:
Назначенный контроллер данных сайта должен обрабатывать потенциальные утечки личных данных в соответствии с законами и нормативными актами соответствующих юрисдикций.
Если FluentCRM настроен на синхронизацию настроек контакта с соответствующим пользователем, злоумышленник может изменить имя пользователя. К счастью, FluentCRM не синхронизирует адреса электронной почты от контактов к пользователям. Если бы FluentCRM это делал, данная уязвимость позволила бы полностью захватить сайт. Злоумышленник мог бы получить привилегированный доступ, изменив адрес электронной почты администратора сайта, а затем сбросив пароль администратора.
Однако другие решения могут синхронизировать все метаданные от контактов к пользователям, например, WP Fusion и API FluentCRM. WP Fusion, вероятно, самый популярный сторонний плагин для синхронизации метаданных контактов между CRM (например, FluentCRM) и WordPress. К счастью, текущая версия WP Fusion не подключена к изменениям метаданных, инициированным из уязвимых форм. Я проинформировал разработчиков WP Fusion, и они не будут устранять это ограничение, пока WPManageNinja не исправят уязвимость.
API FluentCRM также можно использовать для обновления данных контактов и пользователей. Владельцы сайтов, использующие API FluentCRM для обновления адресов электронной почты пользователей, должны отключить это обновление при его инициировании со страницы или шорткода FluentCRM для управления предпочтениями (или добавить мой сниппет для смягчения, чтобы гарантировать, что никакие настройки не могут быть обновлены из уязвимых форм).
FluentCRM позволяет контактам отписываться и управлять предпочтениями на публичных веб-страницах. Ссылки на эти страницы включены в каждую рассылку. Изменения, внесенные на этих страницах, авторизуются с помощью MD5-хэшей адресов электронной почты контактов, передаваемых в качестве параметров URL. MD5-хэш адреса электронной почты не является секретом и может быть вычислен кем угодно. Злоумышленник может использовать неправильное использование хэшей для отписки конкретных контактов или массовой отписки контактов с известными адресами электронной почты.
В то время как страница отписки полагается исключительно на MD5-хэш для авторизации, страница управления предпочтениями требует дополнительный параметр URL под названием ce_id. В данном случае ce_id относится к ID контакта в таблице fc_subscribers. Этот ID представляет собой увеличивающееся целое число. Значение ce_id легко найти, перебрав все возможные значения (пространство поиска — это количество когда-либо зарегистрированных контактов сайта). Пользователи-администраторы, вероятно, имеют низкие значения.
Со страницы управления предпочтениями злоумышленник также может извлечь значение secure_hash контакта. При обновлении адреса электронной почты контакта значение его "secure_hash" сохраняется в cookie с именем fc_hash_secure. Имея этот cookie, злоумышленник может отобразить всю информацию о контакте, предоставляемую шорткодом формы предпочтений FluentCRM.
Ранее упомянутый "secure_hash" — это значение, на которое FluentCRM (в некоторых ситуациях) полагается вместо или как альтернативу MD5-хэшу адреса электронной почты. С момента выхода FluentCRM 2.8.0 страница отписки полагается исключительно на значение secure_hash для авторизации. Страница управления предпочтениями принимает как новое значение secure_hash, так и старый MD5-хэш адреса электронной почты для авторизации.
Хотя значение secure_hash невозможно вывести из адреса электронной почты, его использование в FluentCRM не соответствует хорошим практикам безопасности. Значение secure_hash генерируется один раз для каждого контакта. Оно никогда не обновляется и никогда не истекает. Это проблематично, поскольку значение secure_hash включается в каждое письмо рассылки. Если злоумышленник получает доступ к почтовому ящику контакта, он может бесконечно изменять настройки контакта. Если затронутый контакт связан с пользователем, имеющим права администратора, и изменения адреса электронной почты синхронизируются из FluentCRM в WordPress, то каждое письмо рассылки, отправленное этому контакту, будет содержать бессрочный токен для захвата сайта.
Я сообщил об этой связанной проблеме в WPManageNinja 2023-03-15. Два месяца спустя (2023-05-15) WPManageNinja ответили, что их консультанты по безопасности не считают статическое значение secure_hash проблемой. Консультанты WPManageNinja сказали, что "использовать такие одноразовые токены для идентификации контакта допустимо" и что это "похоже на API-токены SaaS-сервисов, которые не доставляются другим контактам, а отправляются только фактическому контакту, владеющему адресом электронной почты".
WPManageNinja были открыты и сказали мне сообщить, если я все еще считаю это проблемой безопасности, что я и сделал. Я объяснил, почему значения secure_hash нельзя сравнивать с API-токенами. (API-токены можно гарантированно передавать только через TLS-соединения, а доступ к API-токенам можно ограничить. Это не относится к значениям в открытом виде в электронных письмах. Самое главное, API-токены можно отозвать, в то время как у контакта нет возможности отозвать значение secure_hash.)
Позже в тот же день WPManageNinja поблагодарили меня и сказали, что они рассматривают возможность объединения ID записи электронной почты с хэшем. Это решит проблему, если будет реализовано вместе с автоматическим отзывом либо старых (с истечением по времени), либо предыдущих (с истечением по счетчику) значений secure_hash. Эта функция еще не реализована, но я не считаю использование статических хэш-значений частью этого CVE.
В первом квартале 2023 года мы начали миграцию с предыдущего инструмента рассылок (Sendy) на FluentCRM. Я обнаружил уязвимость при интеграции FluentCRM с Nikka Systems Academy (Project Opal). Поскольку мы заменили систему управления подписками FluentCRM нашим собственным плагином, уязвимые формы FluentCRM никогда не влияли на наш сайт или данные наших клиентов.
FluentCRM — отличный плагин, но обработка раскрытия уязвимости компанией WPManageNinja оставляет желать лучшего. Ниже приведен мой список предложений по улучшению ситуации.
Тем не менее, я все еще доверяю WPManageNinja. Ошибки есть во всех программах, и один неудачно обработанный отчет об уязвимости — не повод прекращать использование их плагинов.
Обновление от 2023-06-12: Тот факт, что они все еще пытались скрыть уязвимость в своем журнале изменений, вызывает у меня искреннее беспокойство. (Теперь они добавили CVE.)