phpMyAdmin 5.2.3 - Élevé - À distance - SQLi - Identifiants non assainis dans le JSON du Designer
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-designer-json-sqli
Classe : SQLi Portée : Distante
phpMyAdmin 5.2.3 (tag RELEASE_5_2_3, commit 962857e). L'AJAX Designer save_setting_value fait un json_encode du blob de paramètres et le concatène dans un UPDATE/INSERT entre guillemets simples sur le lien control-user. Le nom d'utilisateur est échappé. Le JSON ne l'est pas. json_encode n'échappe pas une apostrophe.
Un utilisateur connecté envoie en POST index.php?route=/database/designer avec operation=save_setting_value et une apostrophe dans value. queryAsControlUser exécute alors cette chaîne en tant qu'utilisateur de contrôle pma contre pma__designer_settings. Ce compte est le stockage de configuration, pas la boîte SQL de l'utilisateur connecté. phpMyAdmin 6.x enveloppe ce blob dans quoteString sur ControlUser. La 5.2.3 le concatène toujours brut.
Les anciens CVE du designer (2016-6616, 2019-11768, 2019-18622) concernaient le nom d'utilisateur / le nom de base de données. Ce résidu est la colonne JSON settings_data.
| ID | pas encore de CVE |
| Classe | SQLi (control-user sur pma__designer_settings) |
| Portée | Distante (connexion authentifiée par cookie ; Designer + pma__designer_settings activés) |
| CWE | CWE-89 |
| CVSS | Élevé : 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Produit | phpMyAdmin |
| Affecté | 5.2.3 tag RELEASE_5_2_3 (962857e) |
| Auth | Connexion authentifiée par cookie. Designer + pma__designer_settings activés. |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:19220 uniquement |
Un utilisateur phpMyAdmin connecté capable d'ouvrir le Designer peut injecter du SQL en tant que control user sur pma__designer_settings.
| Privilège | Méthode / chemin | Prouvé en lab ou déduit |
|---|---|---|
| Casser la chaîne UPDATE/INSERT du control-user (intégrité du SQL pmadb) | POST index.php?route=/database/designer operation=save_setting_value avec une apostrophe dans value | Prouvé en lab. General log : SET settings_data = '{"snap_line":"PMA-DESIGNER-JSON-SQLI-WITNESS'#" }' brut. quoteString absent |
Tronquer son propre settings_data pour qu'il ne soit plus du JSON (intégrité de sa propre ligne) | Même POST ; # commente le reste de la requête | Prouvé en lab. Le blob appuser contient le témoin et n'est pas du JSON valide. Le save propre grid-ok a disparu |
| Écraser les lignes designer d'autres utilisateurs sans requêtes empilées (intégrité de la ligne victime) | Même # commente WHERE username = '...' | Prouvé en lab. La graine victim {"keep":"safe"} est devenue le blob témoin tronqué |
| Requêtes supplémentaires en tant que control user | Même sink si le lien mysqli de contrôle autorise le multi-query | Déduit. Par défaut mysqli::query est mono-requête. Non activé ici |
Atteindre d'autres tables pmadb (bookmarks, history, pma__userconfig) | Uniquement si des requêtes empilées ou une évasion de type écriture est possible | Déduit. Le control user de ce lab n'a que du DML sur phpmyadmin.* |
Fermé sur ce lab : accès non authentifié, la boîte SQL de l'appuser connecté (appdb uniquement ; appuser n'a aucun GRANT sur phpmyadmin), shell OS, et requêtes empilées. La fonctionnalité est sans effet si pmadb / designer settings est désactivé (c'est un FAIL, pas ce résidu).
Huit chasses parallèles dans le code source de RELEASE_5_2_3. saveSetting concatène json_encode dans '...'. Le nom d'utilisateur passe par escapeString. La 6.x applique déjà quoteString à ce blob. La 5.2.3 non.
Fausses pistes : injecter sur le nom d'utilisateur (il est échappé) ; attendre une #1064 (le # commente le reste, donc MySQL accepte l'UPDATE tronqué) ; considérer les requêtes empilées comme prouvées (mysqli par défaut est mono-requête).
python3 phpmyadmin-designer-json-sqli-Abraxas-Labs.py
ou
cd lab
./run.sh
Loopback uniquement : http://127.0.0.1:19220. Images phpmyadmin:5.2.3 et mysql:8.0. Projet Compose phpmyadmin-designer-json-sqli. Témoin 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 sur le blob JSON, comme RecentFavoriteTable::saveToDb() et phpMyAdmin 6.x sur cette colonne. Ne pas placer la sortie de json_encode à l'intérieur d'un littéral SQL entre guillemets simples.
962857e)libraries/classes/Database/Designer/Common.php saveSettingControllers/Database/DesignerController.php POST operation=save_setting_valueGET|POST /database/designerGNU Affero GPL v3.0. Voir LICENSE. Lab en loopback uniquement. Aucune garantie.