Аннотация. В Essential Blocks for Gutenberg обработчик AJAX, работающий только на чтение, отдаёт настроенный администратором API-ключ Google Maps любому пользователю с ролью «Автор материалов» (Contributor). Конечная точка проверяет nonce и право
edit_posts, но ни одна из проверок не устанавливает, что вызывающий вправе прочитать секрет администратора. Хрестоматийный случай отсутствия авторизации (CWE-862). Ниже — первопричина, разбор того, почему до точки вывода дотягивается низкопривилегированная учётная запись, и вытекающие из этого меры профилактики и обнаружения. Плагин на момент написания без патча, поэтому рабочий proof of concept удерживается в рамках скоординированного раскрытия до выхода исправления.
Ключевые слова: безопасность WordPress, отсутствие авторизации, CWE-862, нарушение контроля доступа, проверка прав, утечка API-ключа, безопасное программирование.
1. Введение
Essential Blocks for Gutenberg несёт свою библиотеку блоков более чем на 200 000 сайтов. На таком масштабе одна забытая проверка перестаёт быть локальной ошибкой: единственная пропущенная строка способна раскрыть одни и те же учётные данные сразу на сотнях тысяч установок.
Дефект — отсутствие авторизации, один из самых частых классов в экосистеме WordPress. API-ключ Google Maps администратора отдаёт конечная точка, которая подтверждает легитимность запроса, но ни разу не спрашивает, вправе ли вызывающий его читать. Верный запрос, неверный читатель — эта форма повторяется от плагина к плагину и легко проскакивает мимо ревью. Поэтому её и стоит разобрать по косточкам.
2. Затронутый компонент
| Плагин | Essential Blocks for Gutenberg — slug essential-blocks |
| Проверенная версия | 6.4.6 (актуальная на момент тестирования) |
| Активные установки | 200 000+ |
| Тип уязвимости | Отсутствие авторизации / Раскрытие конфиденциальной информации (API-ключа) |
| CWE | CWE-862 Missing Authorization / CWE-200 |
| Требуемые права | Автор материалов (Contributor) (любой пользователь с edit_posts; без manage_options) |
| CVSS 3.1 | ~5.4 (Средняя) AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| Статус | Свежая, подтверждена в коде и воспроизведена в localhost-лаборатории |
3. Первопричина в коде
AJAX-действие google_map_api_key читает общесайтовый, настроенный администратором API-ключ Google Maps из опции eb_settings и возвращает его. Между запросом и этим секретом стоят две вещи: nonce и право edit_posts. Не manage_options.
// Blocks/GoogleMap.php
public function google_map_api_key_callback()
{
if ( ! wp_verify_nonce( sanitize_key( $_POST['admin_nonce'] ), 'admin-nonce' ) ) {
wp_send_json_error( __( 'Nonce verification failed!', 'essential-blocks' ) );
}
if ( ! current_user_can( 'edit_posts' ) ) { // <-- НЕВЕРНАЯ ПРОВЕРКА: низкое право; должно быть manage_options
wp_send_json_error( __( 'You are not authorized!', 'essential-blocks' ) );
}
$settings = get_option( 'eb_settings' );
if ( is_array( $settings ) && isset( $settings['googleMapApi'] ) ) {
wp_send_json_success( $settings['googleMapApi'] ); // <-- возвращает API-ключ администратора
}
...
}Обе проверки — не того рода, что нужен для возвращаемых данных.
wp_verify_nonce() — не проверка авторизации. Она подтверждает, что запрос пришёл из настоящей авторизованной сессии и не подделан третьей стороной, то есть защищает от CSRF, и только. Nonce привязан к пользователю, а не к праву, а значит ничего не говорит о том, что этому пользователю разрешено делать.
Вторая ошибка — проверка edit_posts. То, что уходит в ответ, — настройка администратора, а правом, которое управляет чтением и изменением общесайтовых настроек интеграций, служит manage_options. Спрячьте секрет администратора за edit_posts — право, которое уже есть у каждого «Автора материалов» и «Автора» (Author), — и «авторизационный» барьер пропустит ровно тех, кого обязан отсекать.
Родственный обработчик сохранения той же настройки защищён корректно. Именно это превращает дефект в классическую асимметрию: путь записи закрыт, путь чтения открыт.
4. Как достигается уязвимость (концептуально)
«Автор материалов» — роль низкого доверия: создаёт черновики, но не публикует, не ставит плагины и не видит настроек сайта. Чтобы добраться до обработчика, такому пользователю нужны две вещи, и обе WordPress выдаёт ему в штатном порядке:
- Действительный nonce для действия. Плагин кладёт
admin-nonceв объект JavaScript на экране блочного редактора для каждого, кто может его открыть. Nonce выдаются на пользователя и не ограничены по праву, поэтому «Автор материалов», открывший обычный редактор «новой записи», получает рабочий nonce для этого действия как штатную часть страницы. Никакой уловки не требуется. - Возможность вызвать конечную точку.
admin-ajax.phpотвечает любому аутентифицированному пользователю. Когда обработчик отрабатывает с этим nonce, остаётся единственный барьер — проверкаedit_posts, — и «Автор материалов» его проходит.
Получается, что «авторизация», которую выполняет конечная точка, уже покрыта обычными привилегиями атакующего. Nonce доказывает, что запрос подлинный; проверка прав доказывает, что вызывающий умеет редактировать записи. Ни то ни другое не доказывает главного — что вызывающий вправе читать секрет администратора. В итоге зарезервированный за администратором API-ключ Google Maps раскрывается роли, которая не должна его видеть вовсе.
Пока плагин не исправлен, мы намеренно не публикуем ни точную последовательность запросов, ни значения параметров, ни какие-либо исполняемые команды.
5. Оценка воздействия
«Автор материалов», которому нечего делать с общесайтовыми секретами интеграций, может прочитать настроенный администратором API-ключ Google Maps. Счёт приходит на аккаунт Google владельца сайта:
- Злоупотребление квотой и биллингом. Утёкший ключ Maps можно гонять на износ, выжигая квоту владельца, а за ней и биллинговый бюджет.
- Использование на несанкционированных доменах. Если ограничения ключа по HTTP-referrer или по приложению слабы либо отсутствуют, ключ работает с подконтрольных атакующему сайтов.
Вектор AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N отражает эту картину: доступ по сети, низкая сложность, низкие права, без взаимодействия с пользователем, высокое воздействие на конфиденциальность (секрет раскрывается целиком), прямого воздействия на целостность и доступность нет. Отсюда честная Средняя (~5.4).
6. Устранение
Авторизуйте по тому праву, которое действительно управляет настройкой. Поменяйте в google_map_api_key_callback() проверку с edit_posts на manage_options, чтобы путь чтения совпал с путём сохранения:
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'You are not authorized!', 'essential-blocks' ) );
}До выхода официального исправленного релиза владельцы сайтов могут сократить риск:
- Проверьте, у кого есть учётные записи «Автор материалов» и «Автор», и удалите недоверенные или бездействующие.
- Ограничьте API-ключ Google Maps в консоли Google Cloud: задайте ограничения по HTTP-referrer на собственные домены и сведите ключ только к тем API, которые он реально вызывает, — тогда утёкший ключ куда менее полезен на стороне.
- Смените (ротируйте) ключ, если недоверенные пользователи имели доступ редактора, и следите за использованием в Google Cloud на предмет аномалий.
7. Обнаружение и усиление защиты для владельцев сайтов
Всё выведено прямо из механики уязвимости:
- Помечайте неожиданные вызовы действия
google_map_api_keyвadmin-ajax.phpиз сессий пользователей «Автор материалов» и «Автор». Легитимно это чтение запускает только администратор, настраивающий параметр. - Следите за ключом Maps в Google Cloud. Внезапные всплески обращений, запросы с незнакомых referrer-ов или регионов, оповещения о биллинге — сигналы того, что ключ утёк.
- Применяйте принцип наименьших привилегий. Выдавайте роли «Автор материалов» и «Автор» только тем, кому они нужны; на сайте без низкопривилегированных учётных записей уязвимости не на что опереться.
- Рассмотрите виртуальный патч. Правило WAF, блокирующее или проверяющее это конкретное AJAX-действие для сессий без прав администратора, — разумная промежуточная мера, но не замена обновлению после выхода исправленной версии.
- Держите плагины обновлёнными и примените исправленный релиз вендора, как только он выйдет.
8. Более широкий урок
Принцип прост и нарушается постоянно: аутентификация и защита от CSRF — это не авторизация. Nonce говорит, что запрос подлинный; он ничего не говорит о том, имеет ли запрашивающий право на данные. Каждая конечная точка, возвращающая или меняющая привилегированные данные, должна делать явную проверку прав под чувствительность этих данных — а не под удобное широкое право, оказавшееся под рукой.
Второй урок — симметрия. Если у настройки есть путь чтения и путь записи, оба заслуживают одинаковой защиты, потому что атакующий всегда прощупает забытый. Ревьюеры и автоматические проверки должны помечать любой обработчик, который возвращает значение административной опции под чем-либо слабее права, управляющего этой опцией.
9. Ответственное раскрытие
О проблеме сообщили вендору плагина приватно и добросовестно в рамках процесса скоординированного раскрытия. Полные детали proof of concept — точная последовательность запросов и значения параметров — удерживаются из этой публичной статьи до выхода исправленной версии или до согласованного срока раскрытия, смотря что наступит раньше. Ничего, что позволило бы провести реальную эксплуатацию, не опубликовано.
Все тесты шли в авторизованной изолированной localhost-лаборатории на инфраструктуре, подконтрольной исследователю, с публично доступным GPL-плагином. Сторонние и рабочие системы не затрагивались. Тестовая среда и учётные записи были удалены после воспроизведения.
Источники
- CWE-862: Missing Authorization — https://cwe.mitre.org/data/definitions/862.html
- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor — https://cwe.mitre.org/data/definitions/200.html
- OWASP: Broken Access Control — https://owasp.org/Top10/A01_2021-Broken_Access_Control/
- Справочник разработчика WordPress — Проверка прав пользователя — https://developer.wordpress.org/plugins/security/checking-user-capabilities/
- Справочник разработчика WordPress — Nonce — https://developer.wordpress.org/plugins/security/nonces/
- Калькулятор CVSS v3.1 от FIRST — https://www.first.org/cvss/calculator/3.1
Опубликовано в защитных и образовательных целях. Noroxi LLC проводит только авторизованные исследования безопасности; операционные детали эксплуатации удерживаются до выхода исправления.
Эксплуатируется на этой неделе · по понедельникам
Новые записи KEV, свежие PoC, разбор WordPress и что сделать на неделе. Без аккаунта.