FreeScout : la vulnérabilité de Polycast que nous avons signalée
GHSA-vcgj-6qfr-7qr6 : un utilisateur FreeScout authentifié pouvait gonfler le cache des consultations et ralentir le helpdesk pour tout le monde. Ce que nous avons trouvé et pourquoi passer à la 1.8.248.
Quand vous ouvrez un ticket dans FreeScout et qu'un collègue consulte la même conversation, son nom apparaît en haut. C'est une petite fonction bien pratique : elle évite que deux personnes répondent au même client au même moment. Pour qu'elle fonctionne, le navigateur de chaque agent envoie régulièrement au serveur une requête qui dit, en substance, « je regarde la conversation numéro X ». Le serveur ne vérifiait ni que cette conversation existait, ni que l'utilisateur avait le droit de la voir. Il acceptait simplement la valeur et l'enregistrait.
C'est le défaut décrit dans l'advisory GHSA-vcgj-6qfr-7qr6, publié le 17 octobre 2026 et corrigé dans FreeScout 1.8.248. C'est nous qui l'avons signalé : la découverte est de Liam Giannini (Liam-G sur GitHub), du groupe de recherche en sécurité de Webcracy. Nous remercions les mainteneurs de FreeScout, qui ont publié la correction dans la version suivante.
Ce qui se passait derrière l'indicateur « est en train de consulter »
FreeScout est l'un des helpdesks open source les plus populaires et les plus répandus : développé depuis 2018, il compte plus de 4'600 étoiles sur GitHub et il est utilisé par de très nombreuses entreprises comme alternative auto-hébergée à des services comme Help Scout ou Zendesk. Il est écrit en PHP, sur Laravel. Avec un projet aussi répandu, une faille n'est jamais le problème de quelques-uns seulement. Les mises à jour en temps réel passent par un composant appelé Polycast, qui reçoit les requêtes périodiques des navigateurs sur l'endpoint POST /polycast/receive.
Chaque requête aboutissait dans une méthode, processConvView(), qui lisait le champ data[conversation_id] et l'utilisait tel quel. Aucun contrôle qu'il s'agissait d'un nombre, aucune limite de longueur, aucune vérification des permissions. La conversation n'était recherchée dans la base de données que dans certains cas, et même quand la recherche échouait, la valeur n'était pas écartée. Pour chaque nouvel identifiant, le serveur créait une entrée de cache dédiée et ajoutait ce même identifiant à un unique tableau partagé, conv_view, qui contient les consultations actives de toute l'installation.
Le détail qui transforme un contrôle manquant en problème de disponibilité, c'est justement ce tableau. Il est lu en entier, modifié et réécrit en entier à chaque requête, avec une durée de vie de vingt minutes. Si quelqu'un y glisse des milliers d'identifiants inventés, chaque écriture suivante devient plus lourde, y compris pour les requêtes légitimes des autres agents, qui utilisent le même objet. Pour ne rien arranger, une commande planifiée, freescout:check-conv-viewers, tourne chaque minute : elle parcourt toutes les entrées et, pour chaque entrée expirée, supprime une clé du cache et génère un événement en temps réel. Plus il y a de fausses entrées, plus la base de données et le système de broadcast ont de travail. En outre, l'endpoint n'avait pas de limite de fréquence spécifique.
Résultat : un seul compte agent, même sans privilèges d'administration, pouvait ralentir le helpdesk pour tout le monde. Requêtes plus lentes, workers occupés, pression sur Redis ou sur le backend de cache configuré, tâches planifiées en retard. Il n'y a ni accès aux données d'autrui ni modification de contenus. GitHub classe le problème en gravité modérée, CVSS 3.1 6.5 (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H), dans la catégorie CWE-400, consommation incontrôlée de ressources.
Pourquoi « il faut être authentifié » ne suffit pas
Il serait facile d'écarter le problème en disant que l'attaquant doit avoir un compte. Dans un helpdesk, pourtant, les comptes sont nombreux et changent souvent : agents saisonniers, collaborateurs externes, fournisseurs à qui l'on ouvre une boîte partagée, identifiants réutilisés depuis un autre service compromis. Le contrôle d'accès de Polycast vérifiait que l'utilisateur était connecté et qu'il pouvait écouter le canal demandé. Il ne disait rien du contenu de la requête. La bonne frontière n'est pas « l'utilisateur est authentifié », mais « l'utilisateur peut voir cette conversation précise ».
Il existe aussi un précédent sur le même endpoint. En juillet avait été publié GHSA-gh3r-jh6q-wrvj (CVE-2026-62856), une faille de gravité élevée, corrigée dans la 1.8.226, qui exploitait les caractères génériques d'une requête LIKE dans la sélection des canaux pour lire les notifications d'autres utilisateurs. Notre cas est différent : le champ vulnérable est data[conversation_id] et l'effet porte sur les ressources, pas sur la confidentialité. Mais le fait que le même point d'entrée ait produit deux advisories en quelques mois en dit long. Les endpoints de polling, ceux que le navigateur appelle toutes les quelques secondes sans que personne n'y pense, reçoivent généralement moins d'attention que les écrans que l'utilisateur voit.
Comment nous l'avons vérifié
Le problème est apparu lors d'une revue du code source de FreeScout 1.8.247 (commit 9d11ff0), en suivant le parcours de la donnée depuis l'endpoint jusqu'à la commande de nettoyage. Dans notre signalement, nous avons décrit comment le reproduire en laboratoire : se connecter en tant qu'agent normal, envoyer quelques requêtes avec des identifiants inexistants, observer le cache et la croissance de l'objet conv_view, puis laisser tourner la commande planifiée. Quelques dizaines d'entrées suffisent pour voir le phénomène : pas besoin de faire tomber un helpdesk pour démontrer qu'il peut tomber.
La correction dans la 1.8.248
Les notes de version de la version 1.8.248 mentionnent l'assainissement de l'identifiant dans processConvView(). Dans le code corrigé, la valeur n'est acceptée que s'il s'agit d'un entier positif d'au plus dix chiffres, l'utilisateur doit être authentifié et, avant toute écriture dans le cache, on vérifie qu'il peut effectivement voir la conversation. Une requête avec un faux identifiant, ou portant sur une conversation inaccessible, ne laisse plus de trace.
Dans notre signalement, nous avions aussi proposé d'autres mesures : une limite de fréquence dédiée pour l'endpoint Polycast, un plafond du nombre de consultations actives par utilisateur et par conversation, et surtout le remplacement du tableau global par une structure par conversation, afin de ne pas tout réécrire à chaque requête. La validation assortie du contrôle des permissions ferme le chemin d'attaque décrit dans l'advisory. Les autres mesures relèvent de la défense en profondeur, utiles contre de futurs abus, et restent un choix de conception des mainteneurs.
La même version corrige trois autres advisories : GHSA-w3jr-fphw-whgv, sur des conversations précédentes visibles par des utilisateurs censés ne voir que celles qui leur sont assignées ; GHSA-c8rg-2r2h-5vgc, sur la création de plusieurs sessions en utilisant la même invitation en parallèle ; et GHSA-cxf4-7mrp-vvpr, un problème de caractères de contrôle dans la dépendance league/flysystem. Cela suffit déjà pour ne pas repousser la mise à jour.
Que faire si vous utilisez FreeScout
Si votre installation est antérieure à la 1.8.248, mettez-la à jour. L'advisory n'indique pas de solution de contournement, et désactiver Polycast reviendrait à perdre les mises à jour en temps réel sur lesquelles repose l'interface. Avant la mise à jour, mieux vaut faire une sauvegarde de la base de données et du dossier des modules : beaucoup de problèmes après une mise à niveau de FreeScout viennent de modules tiers pas alignés, plus que du cœur.
Si vous avez constaté des ralentissements inexpliqués du helpdesk, il vaut aussi la peine de regarder la taille de l'entrée conv_view dans le cache. Une valeur contenant beaucoup plus d'entrées qu'il n'y a de conversations réellement ouvertes par les agents est un signal à approfondir. Après la mise à jour, de toute façon, les entrées existantes expirent d'elles-mêmes en vingt minutes.
Et si FreeScout tourne sur un serveur que personne n'a contrôlé depuis des mois, cet advisory n'est probablement pas votre seul problème. Un helpdesk contient les e-mails des clients, des pièces jointes, parfois des données personnelles sensibles : il mérite la même maintenance que le site de l'entreprise, sinon davantage.
Pourquoi nous faisons de la recherche sur les logiciels open source
Beaucoup de nos clients utilisent des outils open source auto-hébergés, et nous les recommandons souvent : pas de licence par utilisateur, des données sur son propre serveur, du code qu'on peut lire. Mais « on peut le lire » ne veut pas dire que quelqu'un le lit. Consacrer une partie de notre temps à la revue des projets que nous installons, et signaler de manière responsable ce que nous trouvons à leurs mainteneurs, est la façon la plus concrète que nous connaissions de rendre quelque chose à ces projets. Et de savoir vraiment ce que nous mettons en production.
Si vous souhaitez un contrôle similaire de votre helpdesk, de votre logiciel de gestion ou d'une application développée sur mesure, nous en parlerons volontiers. Notre travail de penetration testing part justement de là : lire le code et la configuration, comprendre où une donnée n'est pas contrôlée, et vous dire précisément ce que nous avons vérifié et ce que nous n'avons pas vérifié.
VOUS AVEZ UN PROJET?
Discutons de comment nous pouvons aider votre entreprise avec des solutions numériques sur mesure.
CONTACTEZ-NOUS