
phpMyAdmin 5.2.3 - Alta - Remota - CSRF - eliminación de token en /sql
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-csrf-sql
Write-up: https://abraxaslabs.tech/research/phpmyadmin-csrf-sql
Clase: CSRF Alcance: Remoto
phpMyAdmin 5.2.3 (tag RELEASE_5_2_3, commit 962857e). Common.php construye la petición PSR-7 a partir de las globales antes de checkTokenRequestParam. Cuando no coinciden, Sanitize::removeRequestVars limpia $_POST y $_GET, pero no esa instantánea. Después, $sql_query se copia desde $request->getParsedBodyParam('sql_query'). Las peticiones POST AJAX se abortan cuando el token no coincide. Las peticiones POST no AJAX continúan. SqlController prefiere el $_POST['sql_query'] ya limpiado y, en caso contrario, conserva la global.
Basta con una víctima que tenga la cookie de sesión de phpMyAdmin. Envía un POST a index.php?route=/sql con sql_query y sin un token válido, y sin ajax_request. El SELECT se ejecuta como ese usuario de MySQL. El valor predeterminado CookieSameSite=Strict en 5.2.3 bloquea muchos navegadores entre sitios. Same-site, Lax, None o la autenticación HTTP siguen siendo vulnerables. En cualquier caso, se trata de un control CSRF defectuoso.
| ID | aún sin CVE |
| Clase | CSRF |
| Alcance | Remoto. El valor predeterminado CookieSameSite=Strict bloquea muchos navegadores entre sitios. Same-site / Lax / None / autenticación HTTP siguen afectados. |
| CWE | CWE-352 |
| CVSS | Alto: 8.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| Producto | phpMyAdmin |
| Afectado | 5.2.3 tag RELEASE_5_2_3 (962857e) |
| Autenticación | Cookie de sesión de phpMyAdmin de la víctima (o autenticación HTTP). Sin token CSRF válido. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1:19240 |
Cualquiera que pueda hacer que el navegador de la víctima envíe un POST a phpMyAdmin sin ajax_request puede ejecutar SQL como ese usuario de MySQL.
| Privilegio | Método / ruta | Demostrado en laboratorio o inferido |
|---|---|---|
| Ejecutar SQL del atacante como la cuenta MySQL de la víctima (integridad + reconocimiento de ese servidor SQL) | POST index.php?route=/sql sql_query=... db=... sin token, sin ajax_request | Demostrado en laboratorio. El cuerpo de la respuesta contenía PMA-CSRF-SQL-WITNESS. El registro general mostró el SELECT como appuser |
| Abortar el mismo manejador en AJAX | El mismo POST con ajax_request=1 | Demostrado en laboratorio. Token mismatch. La fila marcadora del INSERT no estaba presente. El registro general no ejecutó ese INSERT |
Evitar manejadores que solo leen el $_POST limpiado | POST /database/structure/drop-table sin token | Demostrado en laboratorio. keepme seguía presente |
La misma brecha en la exportación (SaveDir), DROP/TRUNCATE de particiones, bloqueo de cuentas, /config/set, creación de pmadb | Cualquier manejador que lea el cuerpo PSR-7 después de la limpieza | Inferido. No se ejercitó |
Descartado en este laboratorio: PMA sin autenticación (se requiere primero iniciar sesión con cookie), rutas AJAX (salen cuando no coinciden), drop-table sin token, shell del sistema operativo. El valor predeterminado Strict SameSite implica que un formulario clásico entre sitios a menudo no enviará la cookie; lo que queda sigue siendo una comprobación CSRF fallida en despliegues same-site y Lax/None.
Ocho búsquedas paralelas en el código fuente de RELEASE_5_2_3. Common.php crea $request = createFromGlobals() antes de checkTokenRequestParam(). Cuando no coinciden, Sanitize::removeRequestVars() limpia solo $_POST/$_GET. Las peticiones no AJAX continúan. SqlController usa la global $sql_query si $_POST está vacío. Ruta GET|POST /sql.
Turnos incorrectos: tratar AJAX /sql como el remanente (aborta por Token mismatch); tratar drop-table como el remanente (ese handler solo lee $_POST filtrado); tratar Strict SameSite por defecto como "CSRF está cerrado" (el control sigue roto; same-site / Lax / None permanecen).
python3 phpmyadmin-csrf-sql-Abraxas-Labs.py
o
cd lab
./run.sh
Solo loopback: http://127.0.0.1:19240. Imágenes phpmyadmin:5.2.3 y mysql:8.0. Proyecto Compose phpmyadmin-csrf-sql. El PoC es un POST loopback del mismo sitio (Strict SameSite aún envía la cookie). Testigo PMA-CSRF-SQL-WITNESS.
SUCCESS phpmyadmin-csrf-sql sql-ran=yes ajax-abort=yes drop-held=yes PMA-CSRF-SQL-WITNESS
En caso de discrepancia, reemplace la solicitud con un cuerpo vacío, o rechace todas las solicitudes POST, no solo las AJAX. No copie sql_query de una solicitud obsoleta. Falle de forma segura como en el cierre de sesión.
962857e)libraries/classes/Common.php instantánea de la solicitud antes de la eliminación del tokenSanitize::removeRequestVars limpia $_POST/$_GET únicamenteSqlController global $sql_queryGNU Affero GPL v3.0. Consulte LICENSE. Solo para laboratorio en loopback. Sin garantía.