
phpMyAdmin 5.2.3 - Hoch - Remote - CSRF - Token-Strip auf /sql
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-csrf-sql
Klasse: CSRF Reichweite: Remote
phpMyAdmin 5.2.3 (Tag RELEASE_5_2_3, Commit 962857e). Common.php erstellt die PSR-7-Anfrage aus den Globals vor checkTokenRequestParam. Bei Nichtübereinstimmung löscht Sanitize::removeRequestVars $_POST und $_GET, aber nicht diesen Snapshot. $sql_query wird dann aus $request->getParsedBodyParam('sql_query') kopiert. AJAX-POSTs brechen bei Token-Nichtübereinstimmung ab. Nicht-AJAX-POSTs werden fortgesetzt. SqlController bevorzugt das bereinigte $_POST['sql_query'] und behält andernfalls das Global bei.
Ein Opfer mit einem phpMyAdmin-Session-Cookie genügt. POST an index.php?route=/sql mit sql_query und ohne gültiges Token sowie ohne ajax_request. Das SELECT wird als dieser MySQL-Benutzer ausgeführt. Das standardmäßige CookieSameSite=Strict in 5.2.3 blockiert viele Cross-Site-Browser. Same-Site, Lax, None oder HTTP-Auth treffen es weiterhin. So oder so handelt es sich um eine fehlerhafte CSRF-Kontrolle.
| ID | noch keine CVE |
| Klasse | CSRF |
| Reichweite | Remote. Das standardmäßige CookieSameSite=Strict blockiert viele Cross-Site-Browser. Same-Site / Lax / None / HTTP-Auth bleiben bestehen. |
| CWE | CWE-352 |
| CVSS | Hoch: 8.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| Produkt | phpMyAdmin |
| Betroffen | 5.2.3 Tag RELEASE_5_2_3 (962857e) |
| Auth | phpMyAdmin-Session-Cookie des Opfers (oder HTTP-Auth). Kein gültiges CSRF-Token. |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1:19240 |
Jeder, der den Browser des Opfers dazu bringen kann, ohne ajax_request ein POST an phpMyAdmin zu senden, kann SQL als dieser MySQL-Benutzer ausführen.
| Berechtigung | Methode / Pfad | Im Lab nachgewiesen oder abgeleitet |
|---|---|---|
| Angreifer-SQL als das MySQL-Konto des Opfers ausführen (Integrität + Recon dieser SQL-Box) | POST index.php?route=/sql sql_query=... db=... kein token, kein ajax_request | Im Lab nachgewiesen. Der Ergebnis-Body enthielt PMA-CSRF-SQL-WITNESS. Das General Log zeigte das SELECT als appuser |
| Denselben Handler bei AJAX abbrechen | Dasselbe POST mit ajax_request=1 | Im Lab nachgewiesen. Token mismatch. INSERT-Marker-Zeile fehlt. Das General Log führte dieses INSERT nicht aus |
Handler überspringen, die nur das bereinigte $_POST lesen | POST /database/structure/drop-table ohne Token | Im Lab nachgewiesen. keepme weiterhin vorhanden |
Dieselbe Lücke beim Export (SaveDir), Partition DROP/TRUNCATE, Account-Sperre, /config/set, pmadb-Erstellung | Jeder Handler, der den PSR-7-Body nach der Bereinigung liest | Abgeleitet. Nicht ausgeführt |
In diesem Lab ausgeschlossen: unauthentifiziertes PMA (Cookie-Login zuerst erforderlich), AJAX-Routen (sie beenden sich bei Nichtübereinstimmung), drop-table ohne Token, OS-Shell. Das standardmäßige Strict SameSite bedeutet, dass ein klassisches Cross-Site-Formular das Cookie oft nicht senden wird; der Rest ist weiterhin eine fehlgeschlagene CSRF-Prüfung bei Same-Site- und bei Lax/None-Deployments.
Acht parallele Quellcode-Suchen in RELEASE_5_2_3. Common.php erstellt $request = createFromGlobals() vor checkTokenRequestParam(). Bei Nichtübereinstimmung löscht Sanitize::removeRequestVars() nur $_POST/$_GET. Nicht-AJAX wird fortgesetzt. SqlController verwendet das globale $sql_query, wenn $_POST leer ist. Route GET|POST /sql.
Irrwege: AJAX /sql als den Rest zu betrachten (es bricht mit Token mismatch ab); drop-table als den Rest zu betrachten (dieser Handler liest nur das bereinigte $_POST); das standardmäßige Strict SameSite als „CSRF ist geschlossen“ zu betrachten (die Kontrolle ist weiterhin fehlerhaft; Same-Site / Lax / None bleiben bestehen).
python3 phpmyadmin-csrf-sql-Abraxas-Labs.py
oder
cd lab
./run.sh
Nur Loopback: http://127.0.0.1:19240. Images phpmyadmin:5.2.3 und mysql:8.0. Compose-Projekt phpmyadmin-csrf-sql. Der PoC ist ein Same-Site-Loopback-POST (Strict SameSite sendet das Cookie trotzdem). Witness PMA-CSRF-SQL-WITNESS.
SUCCESS phpmyadmin-csrf-sql sql-ran=yes ajax-abort=yes drop-held=yes PMA-CSRF-SQL-WITNESS
Bei Nichtübereinstimmung die Anfrage durch einen leeren Body ersetzen oder alle POSTs ablehnen, nicht nur AJAX. sql_query nicht aus einer veralteten Anfrage kopieren. Fail closed wie beim Logout.
962857e)libraries/classes/Common.php Request-Snapshot vor dem Token-StripSanitize::removeRequestVars löscht nur $_POST/$_GETSqlController globales $sql_queryGNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.