CVE-2026-84385 / FG-IR-26-164 concerne un défaut de contrôle d’accès dans FortiSOAR on-premise et PaaS. Fortinet le classe sous CWE-284 et publie un score CVSS de base de 5,4 — Medium et un score temporel de 4,9. Les tests de Thomas SAUTIER documentent l’accès aux flux STOMP/SockJS depuis un compte sans permissions fonctionnelles.
Le résultat principal est une injection de notifications : un message envoyé par le compte restreint apparaît dans la GUI d’autres utilisateurs, dont les administrateurs. L’autre résultat concerne l’abonnement aux événements : le compte voit des opérations et des identifiants, mais pas le contenu des fiches concernées.
1. Versions concernées et correctifs annoncés
L’avis PSIRT donne le même périmètre pour FortiSOAR on-premise et FortiSOAR PaaS.
| Branche | Versions affectées selon l’avis PSIRT | Solution publiée |
|---|---|---|
| 8.0 | Non affectée | Non applicable |
| 7.6 | 7.6.0 à 7.6.6 incluses | 7.6.7 ou supérieure |
| 7.5 | 7.5.0 à 7.5.3 incluses | 7.5.4 ou supérieure |
| 7.4 | Toutes les versions 7.4 | Migration vers une branche corrigée ; aucun correctif 7.4 indiqué. |
| 7.3 | Toutes les versions 7.3 | Migration vers une branche corrigée ; aucun correctif 7.3 indiqué. |
8.0.0 ou supérieure figure également dans les solutions pour les deux modes de déploiement. Cela ne dispense pas de vérifier le chemin de migration, le support et les dépendances de la version choisie.
Pour 7.4 et 7.3, l’avis vise toutes les versions et demande une migration. Le record CVE structuré donne des plages jusqu’à 7.4.5 et 7.3.3 ; nous retenons ici le périmètre plus explicite de l’avis PSIRT. Aucun correctif dans ces deux branches n’est annoncé.
Le record a été réservé le 1er septembre 2026, publié le 8 septembre 2026 et mis à jour le 10 septembre 2026. Le 8 septembre est aussi la date de publication initiale indiquée dans l’avis PSIRT. Ces dates ne remplacent pas celles des échanges de recherche.
2. Un compte qui peut se connecter, sans permissions sur les modules
Le compte de laboratoire est none_user, avec un profil décrit comme Restricted. La vérification des droits effectifs se fait dans Security Management → Users → View Effective Role Permissions. Le signalement précise l’absence de droits de lecture sur les modules, d’écriture et d’administration. Le compte conserve seulement la capacité de s’authentifier.
La reproduction détaillée du 5 février 2026 porte sur FortiSOAR 7.6.5-build5662. Une session d’administration est ouverte pour observer le résultat dans la GUI, sur les vues Alerts ou Incidents avec le filtre All. Une autre session, celle du compte restreint, sert aux essais WebSocket.
Il ne s’agit pas d’un accès anonyme ni d’un contournement du formulaire de connexion. Une authentification valide reste nécessaire. Les tests de cette installation ne suffisent pas à décrire toutes les configurations PaaS ; leur inclusion dans le périmètre affecté vient du record de Fortinet.
3. Le point de contrôle manquant sur les messages
Le test utilise STOMP au-dessus de SockJS/WebSocket. Ces couches ont des fonctions différentes : WebSocket transporte les échanges, SockJS les encadre pour le client, et STOMP indique notamment à quelle destination s’abonner ou envoyer un message.
Le chemin de transport relevé est /websocket/cyops-websocket/, avec des segments de serveur et de session avant le suffixe /websocket. Le test s’authentifie via /auth/authenticate puis établit la session STOMP. L’authentification de cette connexion ne vaut pas autorisation pour toutes les destinations.
Session authentifiée → ouverture du transport WebSocket/SockJS
CONNECT → établissement de la session STOMP
SUBSCRIBE → demande d’abonnement à une destination
SEND → envoi d’un message vers une destination
MESSAGE → livraison d’un message à un abonné Deux décisions doivent être contrôlées séparément : SUBSCRIBE, qui demande à recevoir des événements, et SEND, qui demande à publier un message. Un compte peut avoir le droit d’ouvrir une session sans avoir le droit de lire ou d’écrire un flux réservé.
Le signalement relève des abonnements et publications acceptés malgré les restrictions du compte. Cela indique un défaut d’autorisation sur les destinations testées. Le code interne du produit n’a pas été audité ici : le schéma de configuration Spring proposé dans le premier signalement était une piste de correction, pas la preuve qu’une méthode précise manquait dans le produit.
4. Une fausse notification apparaît dans la GUI
La première preuve de concept affiche des abonnements acceptés et une réponse MESSAGE après injection. Ce retour montre la circulation d’un message, mais « Injection Sent! » ne suffit pas à prouver qu’un administrateur le voit. Le PSIRT demande justement cette vérification après son premier essai.
La reproduction affinée envoie un message de test sur plusieurs destinations candidates, notamment /topic/events, /topic/alerts, /topic/security et /topic/audit. Thomas SAUTIER rapporte alors un bandeau rouge en haut de la GUI, sans rafraîchissement, visible pour les utilisateurs connectés observés, dont les administrateurs.
CRITICAL PWN: Unauthorized WebSocket injection Le corps du message de test emploie plusieurs champs susceptibles d’être interprétés par le client. Voici un extrait, sans timestamp ni valeur d’authentification :
{
"message": "CRITICAL PWN: Unauthorized WebSocket injection",
"content": "CRITICAL PWN: Unauthorized WebSocket injection",
"severity": "CRITICAL",
"source": "Security Assessment",
"type": "Security Alert",
"user": "System"
} Les valeurs severity, source et user sont fournies par l’émetteur. Elles ne prouvent pas que le serveur a attribué un rôle System au compte. Le résultat est la falsification d’une notification visible, pas une modification démontrée du rôle du compte.
Le 11 février, le PSIRT confirme avoir reproduit l’absence de contrôle de rôle sur le flux WebSocket avec un utilisateur sans permissions et l’affichage du bandeau à d’autres utilisateurs connectés.
Le test multi-destinations permet de vérifier la visibilité, mais ne permet pas d’attribuer avec certitude le bandeau à chacune des destinations individuellement. Il ne prouve pas non plus que toute destination imaginable existe ou accepte ces opérations. Pour une recette, il faut isoler les destinations et éviter les envois répétés.
Le compte none_user sans permissions fonctionnelles s’authentifie sur FortiSOAR 7.6.5-build5662. Il établit une session STOMP/SockJS et publie un message de test. Un bandeau rouge apparaît dans la GUI des sessions connectées observées ; le PSIRT confirme la reproduction. Cela ne démontre ni création persistante d’un incident ni exécution d’un playbook.
Télécharger le schéma en SVG · version claire5. Le retest limite la divulgation aux métadonnées
Le signalement initial parlait de données sensibles complètes. Cette conclusion a été corrigée après retest. Le PSIRT constate que les messages décrivent les opérations effectuées et les noms des champs modifiés, sans leurs valeurs. Thomas SAUTIER confirme ce constat le 13 février.
5.1. Opération et identifiants d’objet
{
"operation": "create",
"entityUuid": [
"/api/3/people/00000000-0000-4000-8000-000000000001"
],
"sourceWebsocketId": "00000000-0000-4000-8000-000000000002"
} operation révèle ici une création. entityUuid indique le type et l’identifiant de l’objet concerné. sourceWebsocketId identifie une origine de flux ; ce n’est pas, à lui seul, le nom d’un administrateur ou un jeton permettant d’utiliser sa session.
5.2. Noms des champs, sans valeurs
{
"operation": "update",
"sourceWebsocketId": "00000000-0000-4000-8000-000000000002",
"changeData": [
"firstname",
"lastname",
"title"
]
} La liste changeData mentionne firstname, lastname et title. Elle ne donne ni le prénom, ni le nom, ni le titre saisis. Le préfixe d’une destination de type /topic/roles/<uuid-du-rôle>/people peut également révéler un identifiant de rôle ; cela ne prouve pas une cartographie exhaustive des droits.
5.3. La lecture REST des objets est refusée
Le retest indique que les demandes REST visant les objets identifiés par les événements retournent HTTP 403 Forbidden. Le contrôle d’accès REST résiste donc dans ce contrôle : connaître un UUID ne donne pas le droit de lire l’objet.
Les données visibles renseignent néanmoins sur l’activité : création ou modification d’un objet, catégorie concernée et rythme d’arrivée des événements. Des corrélations sont possibles, mais déduire l’identité d’un opérateur, le contenu d’un incident ou une décision de remédiation demande d’autres preuves. Ces déductions ne sont pas des résultats de ce test.
6. Résultats établis et limites
| Point contrôlé | Résultat documenté | Ce qui reste non démontré |
|---|---|---|
| Authentification | Compte valide sans permissions fonctionnelles. | Accès anonyme ou vol d’une autre session. |
| Publication | Notification injectée visible dans la GUI ; reproduction confirmée par le PSIRT. | Exécution de code, modification de rôle ou création persistante d’une alerte métier. |
| Abonnement | Événements et métadonnées reçus par le compte restreint. | Autorisation universelle sur toutes les destinations ou tous les objets. |
| Contenu des fiches | Pas de valeurs de champs dans les événements du retest. | Exfiltration des données complètes d’utilisateurs ou d’incidents. |
| API REST | Lecture des objets concernés refusée par HTTP 403 lors du retest. | Contournement général de l’API REST. |
| Correction | Versions corrigées annoncées dans le record CNA. | Nouvel essai de ces firmwares réalisé pour cet article. |
Un bandeau visible dans la GUI n’est pas la preuve qu’un incident a été enregistré en base, qu’un playbook a démarré ou qu’une action a été envoyée à un équipement. Le compte peut tromper le canal de notification ; les conséquences sur les automatisations nécessitent des vérifications supplémentaires.
7. Chronologie des échanges avec le PSIRT
- 18 janvier 2026 : accusé de réception automatique du signalement.
- 19 janvier 2026 : accusé de réception et annonce de l’ouverture d’une investigation, dans le message repris dans le fil.
- 29 janvier : précisions sur les droits effectifs de none_user, les abonnements et la première preuve de concept.
- 4 février : le PSIRT indique que l’envoi est visible dans le terminal, mais demande une preuve de son affichage dans la GUI administrateur.
- 5 février : reproduction affinée sur 7.6.5-build5662 et description du bandeau visible sans rafraîchissement.
- 11 février : le PSIRT confirme le défaut de contrôle de rôle et la diffusion du bandeau ; il précise la nature des données transmises.
- 13 février : retest de Thomas SAUTIER : divulgation limitée aux métadonnées et refus REST 403 ; correction de l’évaluation initiale.
- 17 février : le PSIRT confirme la reproduction et la transmission à l’équipe de développement, avec attribution CVE et publication prévues après correction.
- 28 avril : le PSIRT annonce une correction réalisée dans une version à venir, avec des rétroportages encore en cours, et communique la cotation temporelle de 4,9.
- 22 juillet : correction confirmée en 8.0.0 et rétroportages annoncés ; le PSIRT vérifie encore les dates de sortie des versions concernées.
- 8 septembre : publication du record CVE-2026-84385 et transmission de l’avis public FG-IR-26-164 par le PSIRT.
Les dates des messages cités dans les fils servent de référence pour les réponses du PSIRT. Les fichiers transmis ou transférés plus tard ne correspondent pas forcément à la date de rédaction du message repris. Cette chronologie résume les points techniques utiles ; elle ne reproduit pas la correspondance privée. L’avis public remercie Thomas Sautier pour son signalement dans le cadre de la divulgation responsable.
8. CVSS : 5,4 de base, 4,9 temporel
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N/E:P/RL:O/RC:C AV:N indique un accès réseau, AC:L une complexité faible et PR:L des privilèges préalables limités. Même sans permissions sur les modules, le compte doit être authentifié. UI:N ne nécessite pas l’action d’une autre personne pour le défaut lui-même ; un scénario ultérieur d’ingénierie sociale peut, lui, dépendre de la réaction d’un opérateur.
Les impacts déclarés sont C:L/I:L/A:N : confidentialité et intégrité limitées, aucun impact de disponibilité retenu. La réception de métadonnées et la falsification des notifications correspondent aux deux premiers constats. La démonstration ne mesure ni déni de service ni perte de disponibilité.
L’avis PSIRT distingue 5,4 pour le score de base et 4,9 pour le score temporel. Ce dernier applique les facteurs E:P (0,94), RL:O (0,95) et RC:C (1), suivis de l’arrondi au dixième supérieur. Le record CVE place 4,9 dans son champ baseScore ; pour éviter cette ambiguïté, cet article reprend les libellés de l’avis. Le vecteur décrit une preuve de concept, un correctif officiel et des informations confirmées ; il ne démontre pas une exploitation active.
L’avis indique Known Exploited: No. C’est le statut annoncé par Fortinet dans l’avis consulté, pas une garantie qu’aucune utilisation malveillante ne puisse survenir.
Pour un SOC, une notification falsifiée peut conduire à vérifier une fausse urgence ou détourner l’attention d’une vraie alerte. Des envois répétés peuvent aussi rendre le canal moins utile, sans qu’un impact de disponibilité ait été mesuré ici. L’absence de fuite des valeurs réduit la portée de la divulgation, mais ne rend pas acceptable la visibilité des événements par un compte qui ne devrait pas les recevoir.
L’enrichissement CISA du 9 septembre 2026 indique Exploitation: none et Technical Impact: total. Ces classifications datées ne constituent ni une preuve de compromission complète dans ce test, ni une garantie d’absence d’exploitation ultérieure.
9. Mettre à jour et maîtriser l’accès à FortiSOAR
Appliquez une version corrigée : 7.5.4, 7.6.7 ou 8.0.0, ou une version supérieure adaptée et prise en charge. Pour les branches 7.3 et 7.4, préparez la migration vers une branche corrigée en suivant le chemin recommandé par Fortinet.
En on-premise, sauvegardez les configurations et vérifiez les dépendances : connecteurs, agents, playbooks, intégrations, certificats et authentification. En PaaS, vérifiez la version effective et le statut de mise à jour avec l’exploitant ou le support ; le mode hébergé ne prouve pas que votre instance a déjà reçu la correction.
En attendant, limitez l’accès à l’application aux sources nécessaires, désactivez les comptes inutilisés et revoyez les droits et les sessions. Une authentification renforcée réduit certains risques de vol de compte, mais ne corrige pas l’autorisation des messages d’un compte valide.
Ne considérez pas un profil sans droits comme un contournement : c’est précisément le profil utilisé dans le test. Ne bloquez pas arbitrairement tout WebSocket sans évaluer l’impact sur la GUI. Le record CNA ne fournit pas de contournement éditeur validé ; le filtrage réseau complète la mise à jour.
Fortinet annonce 7.5.4, 7.6.7 et 8.0.0 ou supérieures pour on-premise et PaaS. Choisir une version prise en charge et suivre le chemin de mise à jour. Vérifier séparément les refus de publication et d’abonnement, conserver le contrôle REST puis recetter les notifications légitimes. Ces contrôles sont proposés, aucun firmware corrigé testé.
Télécharger le schéma en SVG · version claireCe que la correction doit contrôler
Le serveur doit vérifier chaque abonnement et chaque publication selon l’identité, le rôle, le périmètre de données et la destination. Les files personnelles et destinations associées à un rôle doivent être liées au compte courant, sans faire confiance aux identifiants demandés par le client. Les notifications système ne doivent pas accepter une origine privilégiée simplement parce que le client l’inscrit dans un champ JSON.
Ces points sont des exigences de validation, pas une description du code exact livré par Fortinet. Le refus doit rester effectif après reconnexion et changement de droits ; une connexion déjà ouverte mérite aussi un contrôle lors d’une révocation.
10. Vérifier la correction dans un laboratoire autorisé
Les étapes suivantes sont proposées pour votre recette. Aucun firmware corrigé n’a été testé pour cet article. Convenez du périmètre, du message de test, des comptes destinataires, de la fréquence maximale et des conditions d’arrêt.
- Relever la référence : version complète, build, mode on-premise/PaaS, profils et permissions effectives. Préparer un administrateur, un compte restreint et un compte autorisé aux événements nécessaires.
- Isoler les sessions : utiliser des profils de navigateur distincts et contrôler l’identité de chaque connexion. Éviter toute ambiguïté avec une session administrateur conservée.
- Distinguer connexion et autorisation : une session STOMP établie ne valide pas les droits de SUBSCRIBE ou SEND. Relever le résultat de chaque opération individuellement.
- Tester un abonnement interdit : produire un événement bénin autorisé dans le laboratoire. Vérifier que le compte restreint ne reçoit ni message ni métadonnées de la destination interdite, et qu’un compte légitime reçoit toujours l’événement.
- Tester une publication interdite : envoyer un seul message marqué « TEST AUTORISÉ », vers une destination convenue. Vérifier le refus côté serveur et l’absence de bandeau dans la session d’observation. Ne pas reprendre la diffusion répétée de la preuve de concept.
- Maintenir le contrôle REST : vérifier le refus sur les objets hors périmètre. Garder séparés les résultats du flux et ceux de l’API.
- Vérifier reconnexion et révocation : refaire les contrôles après reconnexion, changement de rôle ou retrait d’autorisation selon les fonctions prises en charge.
- Recetter les usages légitimes : notifications, activité des vues, événements attendus, playbooks et intégrations. Vérifier qu’un refus supplémentaire ne casse pas les fonctions autorisées.
Conservez les réponses, horaires, identités et journaux disponibles avec le firmware testé. L’absence d’événement pendant une fenêtre silencieuse ne prouve pas un refus : le compte autorisé servant de témoin doit confirmer qu’un événement a bien été produit.
11. Examiner une notification suspecte
Les pièces fournies ne contiennent pas une collecte de journaux complète permettant de publier une signature SIEM validée. Pour enquêter, rapprochez les sessions authentifiées, les connexions de flux et les anomalies de notification lorsque ces éléments sont journalisés.
- Vérifier qu’une notification correspond à un objet ou une opération réelle dans l’application, avec un compte autorisé.
- Rechercher des publications ou abonnements inattendus provenant de comptes restreints, si les journaux exposent les destinations.
- Examiner les envois répétés et leur chronologie, sans se fier uniquement aux champs source, user ou severity du message.
- Comparer les droits effectifs, sessions et changements récents de comptes à une référence connue.
Un proxy qui trace l’ouverture d’un WebSocket ne capture pas nécessairement les opérations STOMP qui suivent. Si les journaux ne permettent pas de distinguer les destinations, faites préciser les possibilités de diagnostic par le support. Préservez les traces et limitez les comptes concernés avant de reprendre les vérifications. La mise à jour ne remplace pas l’examen d’un éventuel usage antérieur.
12. Sources et précautions de lecture
- Fortinet PSIRT — FG-IR-26-164, avis de référence, également cité sous fortiguard.fortinet.com.
- CVE-2026-84385 et record JSON CVEProject, consulté le 12 octobre 2026. Le bloc CNA est fourni par Fortinet.
- Résultats de recherche de Thomas SAUTIER et échanges PSIRT de janvier à septembre 2026 : reproduction sur 7.6.5-build5662, confirmation de la diffusion du bandeau et retest limitant la divulgation aux métadonnées.
- MITRE — CWE-284, Improper Access Control et FIRST — spécification CVSS 3.1.
Les versions, solutions, scores de base et temporel et le crédit du chercheur proviennent de l’avis PSIRT de Fortinet, vérifié avec le record CVE officiel. Le fonctionnement WebSocket décrit dans cet article vient des résultats de recherche et des confirmations PSIRT.
Les échanges privés sont synthétisés, sans publier les mails, coordonnées, mots de passe, jetons, adresses du laboratoire ni identifiants réels. Les UUID des exemples sont fictifs. L’article ne fournit pas de script complet de diffusion multi-destinations. Aucun nouvel essai sur FortiSOAR n’a été exécuté pendant sa rédaction.