Aller au contenu

CVE-2026-21643 : Injection SQL Fortinet FortiClient EMS

La CVE-2026-21643 représente un défaut critique de validation des entrées au sein de la console de gestion Fortinet FortiClient EMS 7.4.4. Cette vulnérabilité se manifeste par une injection SQL (SQLi) non authentifiée où l’application ne neutralise pas les caractères spéciaux présents dans le header HTTP Site. Étant donné la nature administrative du serveur EMS, cette faille permet à un attaquant distant de contourner l’authentification, d’exfiltrer des données de configuration sensibles et potentiellement d’atteindre une exécution de code distant (Remote Code Execution - RCE) en exploitant les fonctions PostgreSQL.

L’inclusion de cette CVE dans le catalogue CISA Known Exploited Vulnerabilities (KEV) souligne l’immédiateté de la menace, des campagnes d’exploitation active ayant été observées ciblant des environnements d’entreprise.

Le cœur de la vulnérabilité réside dans le traitement du header Site lors des requêtes vers l’endpoint /api/v1/init_consts. Dans un scénario légitime, ce header est utilisé pour identifier le contexte du tenant ou du site pour la requête. Cependant, le backend ne paramètre pas cette entrée avant de l’incorporer dans une requête SQL.

Lorsqu’une requête atteint /api/v1/init_consts, l’application extrait la valeur du header Site. Cette valeur est ensuite concaténée directement dans une chaîne de requête. Un attaquant peut briser la syntaxe SQL prévue en insérant un point-virgule (;) ou en utilisant des marqueurs de commentaires (--), lui permettant d’ajouter des commandes SQL entièrement nouvelles à l’instruction originale.

La vulnérabilité suit un schéma classique de “Tainted Input” :

  1. Source : HTTP Header [Site] $\rightarrow$ Entrée contrôlée par l’utilisateur.
  2. Sink : Exécution de requête PostgreSQL $\rightarrow$ Concaténation directe.
  3. Impact : Capacité à modifier la logique de la requête, d’accéder au catalogue pg_catalog, ou d’interagir avec le système de fichiers local via COPY ou lo_import/lo_export si l’utilisateur de la base de données possède des privilèges suffisants.

Le processus d’exploitation est simple et ne nécessite aucune authentification.

Les attaquants commencent généralement par vérifier la vulnérabilité en utilisant des injections SQL basées sur les erreurs ou sur le temps (blind SQLi). Un payload de test commun consiste à tenter de récupérer la version de la base de données : Site: tenant1; SELECT version()--

Si le serveur répond avec une chaîne de version PostgreSQL ou une erreur spécifique à la base de données, la vulnérabilité est confirmée.

Une fois confirmée, l’attaquant peut interroger les catalogues système pour cartographier la structure de la base :

  • Extraction des hashs utilisateurs : Site: tenant1; SELECT usename, passwd FROM pg_shadow--
  • Dump des tables de configuration : Site: tenant1; SELECT * FROM config_table--

Selon la configuration de la base de données et les permissions, la RCE est possible. Dans les environnements PostgreSQL, si le compte de service de la base de données possède des privilèges élevés, les attaquants peuvent utiliser des utilitaires comme pg_read_file ou pg_write_file pour manipuler le système d’exploitation. Dans certains cas, des extensions spécifiques peuvent être exploitées pour exécuter des commandes shell directement.

La détection de cette exploitation nécessite une analyse ciblée des logs du serveur web et des traces d’audit de la base de données.

L’indicateur de compromission (IOC) principal est la présence de caractères anormaux dans le header Site des requêtes GET.

  • URL Cible : /api/v1/init_consts
  • Patterns Suspects :
    • Présence de ;, --, /*, ou ' dans le header Site.
    • Mots-clés SQL : SELECT, UNION, INSERT, UPDATE, DROP, SLEEP, pg_sleep.

Les logs PostgreSQL peuvent révéler :

  • Des requêtes inattendues ciblant pg_shadow ou pg_catalog.
  • Une augmentation des messages ERROR: syntax error at or near... accompagnant les requêtes vers /api/v1/init_consts.
  • Des utilisations inexpliquées de commandes COPY ciblant le système de fichiers local.

Les stratégies de détection suivantes doivent être implémentées immédiatement.

title: FortiClient EMS SQLi via Site Header
logsource:
category: webserver
detection:
selection:
url: '/api/v1/init_costns'
http_header_site:
- '*SELECT*'
- '*UNION*'
- '*--;*'
- '*pg_sleep*'
condition: selection

index=web_logs path="/api/v1/init_consts" | search site_header="*SELECT*" OR site_header="*UNION*" OR site_header="*--;*" OR site_header="*pg_sleep*"

  1. Mise à jour : installer la dernière version corrigée fournie par Fortinet pour FortiClient EMS.
  2. Durcissement WAF : implémenter une règle sur le Web Application Firewall (WAF) pour bloquer toute requête vers /api/v1/init_consts dont le header Site contient des mots-clés SQL ou des caractères spéciaux.
  • Validation des entrées : passer de la concaténation de chaînes à l’utilisation systématique de requêtes paramétrées (Prepared Statements).
  • Principe du moindre privilège : s’assurer que le compte de service de la base de données exécutant le backend EMS possède les privilèges minimaux, interdisant l’utilisation de fonctions risquées comme pg_read_file.