Перейти к содержимому
Noroxi
Исследования7 мин

Essential Blocks: роль «Автор материалов» читает API-ключ Google Maps (отсутствие авторизации)

Отсутствие проверки прав в Essential Blocks даёт любому «Автору материалов» API-ключ Google Maps администратора. Разбор первопричины и исправление.

Команда NoroxiТестирование на проникновение и консалтинг

Аннотация. В 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-ключа)
CWECWE-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.

php
// Blocks/GoogleMap.phppublic 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 выдаёт ему в штатном порядке:

  1. Действительный nonce для действия. Плагин кладёт admin-nonce в объект JavaScript на экране блочного редактора для каждого, кто может его открыть. Nonce выдаются на пользователя и не ограничены по праву, поэтому «Автор материалов», открывший обычный редактор «новой записи», получает рабочий nonce для этого действия как штатную часть страницы. Никакой уловки не требуется.
  2. Возможность вызвать конечную точку. 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, чтобы путь чтения совпал с путём сохранения:

php
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-плагином. Сторонние и рабочие системы не затрагивались. Тестовая среда и учётные записи были удалены после воспроизведения.

Источники

Опубликовано в защитных и образовательных целях. Noroxi LLC проводит только авторизованные исследования безопасности; операционные детали эксплуатации удерживаются до выхода исправления.

Эксплуатируется на этой неделе · по понедельникам

Новые записи KEV, свежие PoC, разбор WordPress и что сделать на неделе. Без аккаунта.

Адрес используется только для этой рассылки и никому не передаётся.

Следующая статья

GiveWP 4.18.0: раскрытие данных жертвователей без аутентификации (CWE-862)