phpMyAdmin 5.2.3 — высокий уровень — удалённый — SQLi — несанитизированные идентификаторы в JSON-файле Designer
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-designer-json-sqli
Разбор: https://abraxaslabs.tech/research/phpmyadmin-designer-json-sqli
Класс: SQLi Доступ: Удалённый
phpMyAdmin 5.2.3 (тег RELEASE_5_2_3, коммит 962857e). AJAX-обработчик Designer save_setting_value выполняет json_encode для блоба настроек и конкатенирует его в UPDATE/INSERT с одинарными кавычками для связи control-user. Имя пользователя экранируется. JSON — нет. json_encode не экранирует одинарную кавычку.
Аутентифицированный пользователь отправляет POST на index.php?route=/database/designer с operation=save_setting_value и кавычкой в value. Затем queryAsControlUser выполняет эту строку от имени control-пользователя pma к pma__designer_settings. Этот аккаунт — хранилище конфигурации, а не SQL-сессия вошедшего пользователя. phpMyAdmin 6.x оборачивает этот блоб в quoteString на ControlUser. 5.2.3 по-прежнему конкатенирует его напрямую.
Более старые CVE в Designer (2016-6616, 2019-11768, 2019-18622) касались имени пользователя / имени базы данных. Этот остаток — столбец JSON settings_data.
| ID | CVE пока нет |
| Класс | SQLi (control-user на pma__designer_settings) |
| Доступ | Удалённый (аутентифицированный вход по cookie; Designer + pma__designer_settings включены) |
| CWE | CWE-89 |
| CVSS | Высокий: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Продукт | phpMyAdmin |
| Затронуто | 5.2.3 тег RELEASE_5_2_3 (962857e) |
| Аутентификация | Аутентифицированный вход по cookie. Designer + pma__designer_settings включены. |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1:19220 |
Аутентифицированный пользователь phpMyAdmin, имеющий доступ к Designer, может внедрить SQL от имени control-пользователя в pma__designer_settings.
| Привилегия | Метод / путь | Доказано в лаборатории или предполагается |
|---|---|---|
| Разорвать строку UPDATE/INSERT control-пользователя (целостность SQL в pmadb) | POST index.php?route=/database/designer operation=save_setting_value с кавычкой в value | Доказано в лаборатории. General log: SET settings_data = '{"snap_line":"PMA-DESIGNER-JSON-SQLI-WITNESS'#" }' в сыром виде. quoteString отсутствует |
Обрезать собственный settings_data, чтобы он перестал быть JSON (целостность собственной строки) | Тот же POST; # закомментирует остаток выражения | Доказано в лаборатории. Блоб appuser содержит маркер и не является валидным JSON. Чистое сохранение grid-ok исчезло |
| Перезаписать строки designer других пользователей без stacked-запросов (целостность строки жертвы) | Тот же # закомментирует WHERE username = '...' | Доказано в лаборатории. Засеянный victim {"keep":"safe"} превратился в обрезанный блоб-маркер |
| Дополнительные выражения от имени control-пользователя | Тот же sink, если соединение mysqli control-пользователя допускает multi-query | Предполагается. По умолчанию mysqli::query выполняет одно выражение. Здесь не включено |
Достичь других таблиц pmadb (bookmarks, history, pma__userconfig) | Только если возможны stacked-запросы или выход через запись | Предполагается. Control-пользователь в этой лаборатории имеет только DML на phpmyadmin.* |
Закрыто в этой лаборатории: неаутентифицированный доступ, SQL-сессия вошедшего appuser (только appdb; у appuser нет GRANT на phpmyadmin), OS shell и stacked-запросы. Функция не работает, если pmadb / настройки designer отключены (это FAIL, а не данный остаток).
Восемь параллельных поисков по исходникам RELEASE_5_2_3. saveSetting конкатенирует json_encode в '...'. Имя пользователя обрабатывается через escapeString. 6.x уже применяет quoteString к этому блобу. 5.2.3 — нет.
Неверные шаги: инъекция в имя пользователя (оно экранируется); ожидание #1064 (# закомментирует остаток, поэтому MySQL принимает усечённый UPDATE); трактовка stacked-запросов как доказанных (по умолчанию mysqli использует одиночные запросы).
python3 phpmyadmin-designer-json-sqli-Abraxas-Labs.py
или
cd lab
./run.sh
Только loopback: http://127.0.0.1:19220. Образы phpmyadmin:5.2.3 и mysql:8.0. Compose-проект phpmyadmin-designer-json-sqli. Свидетель PMA-DESIGNER-JSON-SQLI-WITNESS.
SUCCESS phpmyadmin-designer-json-sqli version=5.2.3 how=live raw-concat=yes truncated=true sql-error=false quoteString=no PMA-DESIGNER-JSON-SQLI-WITNESS
quoteString(..., ControlUser) / escapeString для JSON-блоба, так же как в RecentFavoriteTable::saveToDb() и phpMyAdmin 6.x для этого столбца. Не помещайте вывод json_encode внутрь SQL-литерала в одинарных кавычках.
962857e)libraries/classes/Database/Designer/Common.php saveSettingControllers/Database/DesignerController.php POST operation=save_setting_valueGET|POST /database/designerGNU Affero GPL v3.0. См. LICENSE. Только для лабораторной среды с loopback. Без гарантий.