🔍 Contexte

Publié le 3 avril 2026 sur le blog de BZHunt (https://www.bzhunt.fr/blog/cve_glpi/), cet article présente l’anatomie complète d’une chaîne d’exploitation 0-day découverte en février 2026 dans GLPI, l’outil ITSM open source largement déployé en Europe pour la gestion de parcs informatiques, tickets et inventaires d’actifs.

🐛 Vulnérabilités identifiées

Trois CVE ont été assignés, dont deux forment la chaîne critique :

  • CVE-2026-26027 (CVSS 7.5 – High) : Blind Stored XSS non authentifiée via l’endpoint /Inventory. Les champs deviceid, tag et useragent sont stockés sans assainissement HTML dans Agent::handleAgent() et rendus via le filtre Twig |raw, désactivant l’auto-échappement. Périmètre : GLPI 10.0.0–11.0.5.
  • CVE-2026-26026 (CVSS 9.1 – Critical) : SSTI → RCE via double compilation Twig dans QuestionTypeDropdown.php. Le template Twig est reconstruit en concaténant du HTML déjà rendu avec un template non rendu, puis resoumis à renderFromStringTemplate(). La fonction call() (alias de call_user_func_array()) exposée par PhpExtension et les superglobales $_GET/$_POST accessibles comme variables Twig permettent l’exécution de commandes OS. Périmètre : GLPI 11.0.0–11.0.5.
  • CVE-2026-26263 (CVSS 8.1 – High) : SQL Injection non authentifiée dans le moteur de recherche. Indépendante de la chaîne, fera l’objet d’un article séparé.

⛓️ Chaîne d’exploitation complète

  1. Injection XSS : envoi d’une requête POST non authentifiée vers /Inventory avec un payload JavaScript dans le champ tag
  2. Account Takeover : lorsqu’un administrateur consulte Administration → Agents, le payload s’exécute dans sa session, contourne la protection CSRF en récupérant dynamiquement le token, et crée silencieusement un compte super-administrateur
  3. SSTI → RCE : avec le compte créé, l’attaquant injecte {{ call(_get.fn, [_get.a]) }} dans une valeur d’option dropdown, puis déclenche l’exécution via /ajax/common.tabs.php?fn=shell_exec&a=id

💥 Impact

  • Exécution de commandes OS arbitraires sous l’identité du serveur web (www-data)
  • Exfiltration de credentials BDD, fichiers de configuration, données utilisateurs
  • Pivot réseau depuis le serveur GLPI compromis
  • Persistance (web shells, tâches cron, clés SSH, comptes backdoor)
  • Risque supply chain sur l’ensemble du parc IT managé

🛠️ Fichiers clés affectés

  • src/Glpi/Inventory/Conf.php (l.1309) : auth_required = 'none' par défaut
  • src/Agent.php (l.420–434) : stockage sans sanitisation
  • templates/components/form/fields_macros.html.twig (l.787) : filtre |raw
  • src/Glpi/Form/QuestionType/QuestionTypeDropdown.php (l.205) : double compilation
  • src/Glpi/Application/View/Extension/PhpExtension.php (l.90–106) : call() = call_user_func_array()
  • src/Glpi/Application/View/TemplateRenderer.php (l.127–129) : exposition des superglobales

📅 Timeline de divulgation

  • Février 2026 : découverte et signalement à l’équipe GLPI
  • 3 mars 2026 : publication du patch (GLPI 11.0.6)
  • Mars/Avril 2026 : publication de l’article

📄 Nature de l’article

Il s’agit d’une analyse technique approfondie (vulnerability research / full disclosure) publiée par BZHunt après patch, incluant des preuves de concept, des extraits de code source, des payloads d’exploitation et une preuve de RCE confirmée sur GLPI 11.0.5.

🧠 TTPs et IOCs détectés

TTP

  • T1190 — Exploit Public-Facing Application (Initial Access)
  • T1059 — Command and Scripting Interpreter (Execution)
  • T1136 — Create Account (Persistence)
  • T1505.003 — Server Software Component: Web Shell (Persistence)
  • T1552.001 — Unsecured Credentials: Credentials In Files (Credential Access)
  • T1083 — File and Directory Discovery (Discovery)
  • T1021 — Remote Services (Lateral Movement)
  • T1565 — Data Manipulation (Impact)

IOC

  • CVEs : CVE-2026-26026NVD · CIRCL
  • CVEs : CVE-2026-26027NVD · CIRCL
  • CVEs : CVE-2026-26263NVD · CIRCL
  • Fichiers : POC_GLPI_Form_Dropdown_SSTI.py
  • Chemins : src/Glpi/Inventory/Conf.php
  • Chemins : src/Agent.php
  • Chemins : templates/pages/admin/inventory/agent.html.twig
  • Chemins : templates/components/form/fields_macros.html.twig
  • Chemins : src/Glpi/Form/QuestionType/QuestionTypeDropdown.php
  • Chemins : src/Glpi/Form/QuestionType/AbstractQuestionTypeSelectable.php
  • Chemins : src/Glpi/Application/View/Extension/PhpExtension.php
  • Chemins : src/Glpi/Application/View/TemplateRenderer.php

🔗 Source originale : https://www.bzhunt.fr/blog/cve_glpi/