
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
Clase: CSRF Alcance: Remoto
phpMyAdmin 5.2.3 (tag RELEASE_5_2_3, commit 962857e). Common.php construye la petición PSR-7 desde los globales antes de checkTokenRequestParam. En caso de discrepancia, Sanitize::removeRequestVars limpia $_POST y $_GET pero no esa instantánea. $sql_query se copia entonces desde $request->getParsedBodyParam('sql_query'). Las peticiones POST AJAX se abortan ante una discrepancia de token. Las peticiones POST no AJAX continúan. SqlController prefiere el $_POST['sql_query'] eliminado y, en caso contrario, conserva el global.
Basta con una víctima con 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 autenticación HTTP siguen siendo vulnerables. En cualquier caso, se trata de un control CSRF roto.
| 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 permanecen. |
| 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 | Probado en laboratorio o inferido |
|---|---|---|
| Ejecutar SQL del atacante como la cuenta MySQL de la víctima (integridad + reconocimiento de esa caja SQL) | POST index.php?route=/sql sql_query=... db=... sin token, sin ajax_request | Probado en laboratorio. El cuerpo de resultados contenía PMA-CSRF-SQL-WITNESS. El registro general mostró el SELECT como appuser |
| Abortar el mismo manejador en AJAX | Mismo POST con ajax_request=1 | Probado en laboratorio. Token mismatch. Fila marcadora INSERT ausente. El registro general no ejecutó ese INSERT |
Omitir manejadores que solo leen el $_POST eliminado | POST /database/structure/drop-table sin token | Probado en laboratorio. keepme sigue presente |
Misma brecha en export (SaveDir), DROP/TRUNCATE de partición, bloqueo de cuenta, /config/set, creación de pmadb | Cualquier manejador que lea el cuerpo PSR-7 después de la eliminación | Inferido. No ejercitado |
Cerrado en este laboratorio: PMA no autenticado (se requiere primero inicio de sesión con cookie), rutas AJAX (salen ante discrepancia), drop-table sin token, shell del SO. El valor predeterminado Strict SameSite significa que un formulario clásico entre sitios a menudo no enviará la cookie; lo que queda sigue siendo una comprobación CSRF fallida en same-site y en despliegues Lax/None.
Ocho búsquedas paralelas en el código fuente de RELEASE_5_2_3. Common.php crea $request = createFromGlobals() antes de checkTokenRequestParam(). En caso de discrepancia, Sanitize::removeRequestVars() limpia solo $_POST/$_GET. Las peticiones no AJAX continúan. SqlController usa el global $sql_query si $_POST está vacío. Ruta GET|POST /sql.
Caminos equivocados: tratar el AJAX /sql como el residuo (aborta con Token mismatch); tratar drop-table como el residuo (ese manejador solo lee el $_POST eliminado); tratar el Strict SameSite predeterminado 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 same-site (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, reemplazar la petición por un cuerpo vacío, o rechazar todas las peticiones POST, no solo las AJAX. No copiar sql_query de una petición obsoleta. Fallar de forma segura como en el cierre de sesión.
962857e)libraries/classes/Common.php instantánea de la petición antes de la eliminación del tokenSanitize::removeRequestVars limpia solo $_POST/$_GETSqlController global $sql_queryGNU Affero GPL v3.0. Ver LICENSE. Solo laboratorio loopback. Sin garantía.