
PoC pour CVE-2026-53629, injection SQL aveugle dans le filtre du journal d'historique GLPI
Injection SQL aveugle dans le filtre de l'historique des journaux GLPI. CVE-2026-53629, corrigé en 11.0.8 et 10.0.26, cassé depuis 9.4.0.
Nécessite un compte disposant du droit READ sur logs. Le profil Read-Only standard en dispose.
Avis de sécurité : GHSA-cpcj-x335-5cmh Article : comment je l'ai trouvée
Log::convertFiltersValuesToSqlCriteria() divise le filtre affected_fields en key:operator:values. Le correctif pour CVE-2026-29047 a validé l'opérateur et converti l'index du tableau, laissant $key intact.
DBmysqlIterator::analyseCrit() ne met pas de guillemets autour de , et en tant que noms de colonnes. Elle explore récursivement leurs valeurs, et cette récursion se termine sur une branche obsolète qui renvoie les chaînes simples comme SQL brut.
ORANDNOTAinsi, OR comme clé injecte ce que vous voulez dans la clause 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))))))
L'onglet historique fait de même via filters[affected_fields][0].
explode(',', $values) casse tout ce qui contient une virgule, donc SUBSTRING(s,1,1) et IF(a,b,c) sont exclus. CASE WHEN ... THEN ... ELSE ... END et MID(s FROM n FOR 1) font l'affaire. Des littéraux hexadécimaux au lieu de guillemets : 0x676c7069 correspond à glpi.
Le payload s'exécute une fois par ligne dans glpi_logs, donc le sleep se multiplie. Six lignes avec sleep(5) donnent 30 secondes. Sur une instance réelle, réduisez-le à 0.1 ou la requête ne reviendra jamais.
pip install requests
python3 glpi_sqli_extract.py http://glpi.lab.local -u readonly -p readonly
Lit glpi_users.password un caractère à la fois par recherche binaire. --id pour un autre utilisateur, --sleep et --threshold pour des cibles plus lentes.
Le même procédé lit api_token, personal_token et les identifiants SMTP et LDAP dans glpi_configs.
Mettez à jour. Si vous ne le pouvez pas, retirez le droit READ sur logs des profils qui n'en ont pas besoin. En amont, la clé a été ajoutée à la liste blanche :
$allowed_keys = ['linked_action', 'id_search_option', 'itemtype_link'];
if (!in_array($key, $allowed_keys, true)) {
continue;
}
Publié après la sortie du correctif. Ne l'exécutez pas sur des systèmes qui ne vous appartiennent pas.