
phpMyAdmin 5.2.3 — высокий — удалённый — CSRF — удаление токена на /sql
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-csrf-sql
Класс: CSRF Доступ: Удалённый
phpMyAdmin 5.2.3 (тег RELEASE_5_2_3, коммит 962857e). Common.php создаёт PSR-7 запрос из глобальных переменных до checkTokenRequestParam. При несовпадении Sanitize::removeRequestVars очищает $_POST и $_GET, но не этот снимок. Затем $sql_query копируется из $request->getParsedBodyParam('sql_query'). AJAX POST-запросы прерываются при несовпадении токена. Не-AJAX POST-запросы продолжаются. SqlController предпочитает очищенный $_POST['sql_query'] и в противном случае сохраняет глобальную переменную.
Достаточно жертвы с сессионной cookie phpMyAdmin. Отправьте POST на index.php?route=/sql с sql_query и без действительного токена, а также без ajax_request. SELECT выполнится от имени этого пользователя MySQL. Значение по умолчанию CookieSameSite=Strict в 5.2.3 блокирует многие кросс-сайтовые браузеры. Same-site, Lax, None или HTTP-аутентификация всё равно срабатывают. В любом случае это сломанная защита от CSRF.
| ID | CVE пока нет |
| Класс | CSRF |
| Доступ | Удалённый. Значение по умолчанию CookieSameSite=Strict блокирует многие кросс-сайтовые браузеры. Same-site / Lax / None / HTTP-аутентификация остаются. |
| CWE | CWE-352 |
| CVSS | Высокий: 8.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| Продукт | phpMyAdmin |
| Затронуто | 5.2.3 тег RELEASE_5_2_3 (962857e) |
| Аутентификация | Сессионная cookie жертвы phpMyAdmin (или HTTP-аутентификация). Действительный CSRF-токен отсутствует. |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1:19240 |
Любой, кто может заставить браузер жертвы отправить POST в phpMyAdmin без ajax_request, может выполнить SQL от имени этого пользователя MySQL.
| Привилегия | Метод / путь | Доказано в лаборатории или предположено |
|---|---|---|
| Выполнить SQL атакующего от имени учётной записи MySQL жертвы (целостность + разведка этого SQL-сервера) | POST index.php?route=/sql sql_query=... db=... без token, без ajax_request | Доказано в лаборатории. Тело ответа содержало PMA-CSRF-SQL-WITNESS. General log показал SELECT от имени appuser |
| Прервать тот же обработчик при AJAX | Тот же POST с ajax_request=1 | Доказано в лаборатории. Token mismatch. Строка-маркер INSERT отсутствует. General log не выполнил этот INSERT |
Обойти обработчики, которые читают только очищенный $_POST | POST /database/structure/drop-table без токена | Доказано в лаборатории. keepme всё ещё присутствует |
Та же брешь при экспорте (SaveDir), DROP/TRUNCATE раздела, блокировке учётной записи, /config/set, создании pmadb | Любой обработчик, читающий тело PSR-7 после очистки | Предположено. Не проверялось |
Закрыто в этой лаборатории: неаутентифицированный PMA (сначала требуется вход по cookie), AJAX-маршруты (они завершаются при несовпадении), drop-table без токена, OS shell. Значение по умолчанию Strict SameSite означает, что классическая кросс-сайтовая форма часто не отправит cookie; остаток всё равно является неудачной проверкой CSRF на same-site и на развёртываниях с Lax/None.
Восемь параллельных поисков в исходниках RELEASE_5_2_3. Common.php создаёт $request = createFromGlobals() до checkTokenRequestParam(). При несовпадении Sanitize::removeRequestVars() очищает только $_POST/$_GET. Не-AJAX продолжается. SqlController использует глобальную $sql_query, если $_POST пуст. Маршрут GET|POST /sql.
Неверные пути: считать AJAX /sql остатком (он прерывается с Token mismatch); считать drop-table остатком (этот обработчик читает только очищенный $_POST); считать, что значение по умолчанию Strict SameSite означает «CSRF закрыт» (защита всё ещё сломана; same-site / Lax / None остаются).
python3 phpmyadmin-csrf-sql-Abraxas-Labs.py
или
cd lab
./run.sh
Только loopback: http://127.0.0.1:19240. Образы phpmyadmin:5.2.3 и mysql:8.0. Проект Compose phpmyadmin-csrf-sql. PoC — это same-site loopback POST (Strict SameSite всё равно отправляет cookie). Свидетель PMA-CSRF-SQL-WITNESS.
SUCCESS phpmyadmin-csrf-sql sql-ran=yes ajax-abort=yes drop-held=yes PMA-CSRF-SQL-WITNESS
При несовпадении замените запрос на пустое тело или отклоняйте все POST-запросы, а не только AJAX. Не копируйте sql_query из устаревшего запроса. Завершайте безопасно, как при выходе из системы.
962857e)libraries/classes/Common.php снимок запроса до очистки токенаSanitize::removeRequestVars очищает только $_POST/$_GETSqlController глобальная $sql_queryGNU Affero GPL v3.0. См. LICENSE. Только loopback-лаборатория. Без гарантий.