
PoC para CVE-2026-53629, inyección SQL ciega en el filtro del registro de historial de GLPI
Inyección SQL ciega en el filtro del historial de registros de GLPI. CVE-2026-53629, corregida en 11.0.8 y 10.0.26, vulnerable desde 9.4.0.
Requiere cualquier cuenta con el permiso de lectura logs. El perfil estándar de solo lectura lo tiene.
Aviso: GHSA-cpcj-x335-5cmh Análisis: cómo lo encontré
Log::convertFiltersValuesToSqlCriteria() divide el filtro affected_fields en key:operator:values. El parche para CVE-2026-29047 validó el operador e hizo un cast al índice del array, dejando $key intacto.
DBmysqlIterator::analyseCrit() no entrecomilla OR, AND y NOT como nombres de columna. Desciende recursivamente sobre sus valores, y esa recursión termina en una rama obsoleta que devuelve cadenas simples como SQL en crudo.
Así que OR como clave introduce lo que quieras en la cláusula WHERE:
/front/log/export.php?itemtype=Entity&id=0&filter[affected_fields][0]=OR::1 AND sleep(5)
SELECT * FROM `glpi_logs`
WHERE `items_id` = '0' AND `itemtype` = 'Entity'
AND (((((1 AND sleep(5))))))
La pestaña de historial hace lo mismo mediante filters[affected_fields][0].
explode(',', $values) rompe cualquier cosa que contenga una coma, así que SUBSTRING(s,1,1) e IF(a,b,c) quedan descartados. CASE WHEN ... THEN ... ELSE ... END y MID(s FROM n FOR 1) hacen el trabajo. Literales hexadecimales en lugar de comillas: 0x676c7069 es glpi.
El payload se ejecuta una vez por fila en glpi_logs, por lo que el sleep se multiplica. Seis filas con sleep(5) son 30 segundos. En una instancia real bájalo a 0.1 o la petición nunca responde.
pip install requests
python3 glpi_sqli_extract.py http://glpi.lab.local -u readonly -p readonly
Lee glpi_users.password de un carácter a la vez mediante búsqueda binaria. --id para otro usuario, --sleep y --threshold para objetivos más lentos.
El mismo truco lee api_token, personal_token y las credenciales SMTP y LDAP en glpi_configs.
Actualiza. Si no puedes, elimina el permiso de lectura logs de los perfiles que no lo necesiten. Upstream incluyó la clave en la lista blanca:
$allowed_keys = ['linked_action', 'id_search_option', 'itemtype_link'];
if (!in_array($key, $allowed_keys, true)) {
continue;
}
Publicado después de que el parche estuviera disponible. No lo ejecutes en sistemas que no sean tuyos.