Illustration technique abstraite sur un fond gris chaud pâle : un haut panneau de réglages blanc cassé aux légères lignes tracées se trouve à gauche du centre, et son champ le plus bas contient deux petits chevrons cyan imbriqués, l'un dans l'autre. Une fine ligne cyan part du panneau vers un bloc serveur plat couleur ardoise à droite ; une seconde ligne ambre quitte les chevrons imbriqués, passe par-dessus la bordure du panneau et rejoint le même bloc, et un petit carré ambre marque le point de jonction où les deux chemins divergent. Un second bloc serveur, plus estompé, se trouve derrière le premier. L'illustration est une géométrie vectorielle plate avec des ombres douces et des marges généreuses ; aucun texte, lettre, chiffre, personne ni logo d'organisation n'apparaît. Le logo OrcaRouter est composé dans le coin inférieur droit d'une bande blanche sous l'illustration.
AI Safety Incidents

RCE de l’agent IA de Zammad : une balise de modèle imbriquée, une correction d’une lettre

Auteur

Alistair Wren

Date de publication

Derniers modèles · 20Voir tous les modèles →
Benchmarks : Artificial Analysis · mis à jour quotidiennement
Retour à tous les articles

Zammad, le centre d'assistance open source, a publié la version 7.1.2 le 4 août 2026 avec dix-huit correctifs de sécurité ; le premier de la liste corrige une faille d'exécution de code à distance dans les champs de configuration de sa fonctionnalité AI Agent. La vulnérabilité est CVE-2026-84462, divulguée dans l'avis GitHub GHSA-gp3x-9xm8-rcj6 le jour même, et sa plage affectée comprend toutes les installations auto-hébergées dont la version est inférieure ou égale à 7.1.1. Un administrateur ayant le droit de créer ou de modifier un AI Agent pouvait saisir un texte spécialement conçu dans l'un des champs de l'agent, contourner le filtre censé le neutraliser et exécuter des commandes arbitraires sur le serveur hébergeant Zammad — avec la possibilité, selon les termes de l'avis, de « lire, modifier ou détruire toutes les données stockées sur ce serveur ». Aucun autre utilisateur n'a à intervenir : l'avis indique que « le code malveillant s'exécute automatiquement la prochaine fois que l'AI Agent affecté traite un ticket ». GitHub lui attribue une gravité élevée de 8,6 selon CVSS 4.0. L'enregistrement, ses balises de gravité et de préjudice, ainsi que les entrées enregistrées autour de lui sont conservés dans l'Orca AI Incident Archive, qui répertorie cet incident aux côtés du reste de la série.

Ce que l’avis établit

L'avis GitHub, publié le 4 août 2026, est court et exceptionnellement précis sur le mécanisme et les conditions préalables. Il décrit un « filtre de sécurité qui protège la configuration de l'AI Agent de Zammad » qui « peut être contourné en saisissant du texte spécialement conçu dans l'un des champs d'un AI Agent », et il nomme précisément l'acteur : « Un administrateur disposant de l'autorisation de créer ou de modifier des AI Agents pourrait exploiter cela pour exécuter des commandes arbitraires sur le serveur qui héberge Zammad. » La plage affectée est indiquée comme allant jusqu'à 7.1.1 inclus, la version corrigée comme étant 7.1.2. Le rapporteur crédité est colinthebomb1 ; le compte de publication est fliebe92. L'avis ne publie aucune preuve de concept ni aucun détail d'exploitation.

GitHub évalue la faille comme élevée, 8,6 selon CVSS 4.0, avec le vecteur AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H et sans changement de portée. En clair, cela signifie que la faille est atteignable via le réseau à faible complexité, sans exigences d’attaque et sans interaction de l’utilisateur, par un attaquant qui détient déjà des privilèges élevés au sein de l’application, avec un impact élevé sur la confidentialité, l’intégrité et la disponibilité de l’instance Zammad elle-même. L’avis répertorie trois faiblesses : CWE-20, validation d’entrée incorrecte ; CWE-94, injection de code ; et CWE-1336, la classe de moteur de template que MITRE définit comme l’échec à neutraliser une syntaxe spéciale « qui peut être interprétée comme des expressions de template ou d’autres directives de code lorsqu’elle est traitée par le moteur. »

Le correctif a changé une lettre

Le correctif public est le commit e3b0c8df91ad2108c8305be23e8fe6f73fb9718d, soumis avec le message « Maintenance: Improve ERB sanitizer. » GitHub indique une date d’auteur au 7 juillet 2026 et une date de commit au 3 août 2026, soit un jour avant l’avis et la version. Il touche deux fichiers : une ligne de lib/erb_sanitizer.rb et quatorze lignes ajoutées de spécification.

La correction tient en une seule ligne. La méthode escape_tag utilisait sub de Ruby, qui remplace la première correspondance d'un motif dans une chaîne ; elle utilise désormais gsub, qui remplace toutes les correspondances. Dans les deux versions, le remplacement est le même : un délimiteur d'ouverture écrit <% devient <%%, la forme doublée qu'ERB, le moteur de templates de Ruby, affiche comme texte littéral au lieu de l'évaluer. L'avis ne précise pas quel champ d'AI Agent porte le template ; le commit identifie le filtre censé rendre ce template inerte.

A dark HTML card titled 'One line, one letter', kicker 'Zammad fix commit e3b0c8f', subtitle 'lib/erb_sanitizer.rb, method escape_tag, authored 7 July 2026 and committed 3 August 2026 - one day before disclosure'. Two code panels: BEFORE, in amber, shows a red minus beside tag.sub with the opener arguments and the note 'Replaces the first opener only'; AFTER, in cyan, shows a green plus beside tag.gsub and the note 'Replaces every opener'. A second panel headed 'WHY ONE LETTER MATTERED' shows the payload, a literal opener followed by an evaluating tag, arrowed to the same string with the first opener doubled, and explains that the inner tag is never touched. A third row headed 'REGRESSION SPEC, SAME COMMIT' shows the two nested payloads the added tests cover, with the note 'Both must render as literal text, not evaluate'. A footer names commit e3b0c8df91ad2108c8305be23e8fe6f73fb9718d and says the card was rendered by OrcaRouter with no vendor logos. The OrcaRouter logo is composited in the bottom-right corner.

Avec sub, seule la première balise ouvrante de la chaîne a été désamorcée. Une charge utile qui place une seconde balise ouvrante immédiatement après la première survit au filtre : <%<%= 1 + 1 %> devient <%%<%= 1 + 1 %>, où ERB émet la balise ouvrante initiale comme du texte, puis évalue la balise interne. La spécification de régression ajoutée dans le même commit nomme l’astuce sans détour — « with a nested opener smuggled inside a single tag (escape-all-openers bypass) » — et affirme que <%<%= 1 + 1 %> et un <%<%<%= 1 + 1 %> doublement imbriqué doivent tous deux être rendus comme du texte littéral. Cette spécification est la description publique la plus claire de la manière dont le filtre a été contourné, car l’avis lui-même n’en fournit aucune.

La forme du bug est générique plutôt qu’une curiosité propre à Zammad : un échappeur qui s’arrête après la première correspondance est mis en échec par toute entrée contenant une seconde copie imbriquée de la séquence qu’il supprime. Le message de commit qualifie le changement de maintenance, ce qui est la façon dont un correctif de durcissement d’un seul caractère passe habituellement — et c’est pourquoi l’avis, et non le diff, a dû porter l’avertissement.

Sept semaines entre l’avis et la NVD

Le NVD a publié sa fiche pour CVE-2026-84462 le 25 septembre 2026, sept semaines après l'avis, et l'a modifiée pour la dernière fois le 28 septembre. La fiche est marquée « Deferred », ce qui signifie que l'agence n'a pas publié sa propre analyse, et son bloc de métriques attribue le score de 8,6 à security-advisories@github.com en tant que métrique secondaire — la notation de GitHub en sa qualité d'autorité de numérotation CVE, et non une évaluation indépendante du NVD. La même fiche ne comporte aucune configuration CPE, de sorte qu'elle n'associe pas la vulnérabilité à un identifiant de produit versionné.

Ces deux précisions comptent pour quiconque suit les logiciels auto-hébergés au moyen de flux plutôt que de notes de version. Le correctif était public et applicable dès le 4 août ; l’enregistrement lisible par machine est arrivé le 25 septembre ; et même alors, il est arrivé sans l’identifiant produit sur lequel les scanners basés sur CPE effectuent leurs correspondances. Pendant sept semaines, le compte rendu faisant foi de la faille a été l’avis du fournisseur et sa note de version.

A dark HTML timeline card titled 'From commit to CVE record', kicker 'Zammad 7.1.2 - CVE-2026-84462', subtitle 'Five dated points, taken from the fix commit, the GitHub advisory, the Zammad release note and the NVD API'. Five rows: 7 July 2026, fix authored in commit e3b0c8f with the message 'Maintenance: Improve ERB sanitizer'; 3 August 2026, fix committed one day before disclosure; 4 August 2026, GitHub advisory GHSA-gp3x-9xm8-rcj6 published and Zammad 7.1.2 shipped the same day with 18 security fixes; 25 September 2026, NVD publishes CVE-2026-84462 with status Deferred and no CPE configuration, 52 days after disclosure; 29 October 2026, FIRST EPSS read at 0.28 percent probability in 30 days, 20th percentile. An amber rule below reads 'The advisory and the CVE record describe the same flaw. The first was actionable on 4 August; the second arrived as a machine-readable record 52 days later.' A footer credits GitHub, Zammad, NVD and FIRST, and says the card was rendered by OrcaRouter. The OrcaRouter logo is composited in the bottom-right corner.

Ce qui est établi, et ce qui ne l’est pas

Établi : l’avis, la version corrigée, le score CVSS et la modification de code proviennent tous de Zammad et de la base de données d’avis de GitHub, et ils concordent entre eux. L’entrée NVD reprend la description de l’autorité de numérotation sans ajouter d’analyse propre. Sur cette base, l’archive attribue à l’entrée une confiance de niveau A, l’incident n’étant pas contesté.

Non établi, ou non consigné : il n’existe aucune preuve de concept dans l’avis et aucun signalement d’exploitation dans la nature. L’EPSS de FIRST attribue à CVE-2026-84462 une probabilité d’exploitation de 0,28 % dans les trente prochains jours, soit le 20e centile, dans le score publié le 29 octobre 2026. L’archive ne consigne aucun dommage réel et classe l’entrée en gravité moyenne — en dessous de la bande « High » de l’avis lui-même. Ce sont des instruments distincts qui répondent à des questions différentes, ce que la faille permettrait par rapport à ce qui s’est réellement produit, et cet article rapporte les deux plutôt que de les concilier.

La corroboration indépendante est mince. Une recherche de couverture de cette CVE renvoie des bases de données de vulnérabilités qui republient le texte de l’autorité de numérotation, ainsi que la note de version de Zammad elle-même ; aucun média d’actualité ne semble avoir signalé la faille de manière indépendante. Il s’agit d’un constat sur le dossier, et non d’une critique de celui-ci : une exécution de code à distance dans un centre d’assistance qui exige un compte administrateur n’est pas le genre d’événement qui génère une couverture médiatique, et l’absence d’un compte rendu indépendant fait elle-même partie de ce que le dossier documente.

Qui pourrait le déclencher, et qu’est-ce qui a changé

La note de version de Zammad pour la 7.1.2, datée du 4 août 2026, recense les dix-huit vulnérabilités corrigées dans cette version et place en tête le contournement du modèle d’agent IA. Pour les clients hébergés, elle indique : « Aucune action n’est requise. Vos instances ont déjà été corrigées et sécurisées par notre équipe. » Pour les installations auto-hébergées, le ton est plus direct : « Nous vous recommandons vivement de mettre à niveau immédiatement vers la dernière version de Zammad afin de garantir la protection de votre système. » L’avis ne propose aucun contournement, et le dossier ne comporte aucune mesure d’atténuation au-delà de la mise à niveau.

A dark HTML card titled 'Who can pull the trigger', kicker 'CVE-2026-84462 - preconditions', subtitle 'From the GitHub advisory and the Zammad 7.1.2 release note; the score and exploitation figure are labelled separately'. Left column headed 'THE ATTACKER MUST' lists three conditions: hold administrator rights inside Zammad, specifically permission to create or edit AI Agents; reach the agent configuration over the network; supply no interaction from any other user. Right column headed 'THE PAYLOAD THEN' lists three consequences: runs on the server that hosts Zammad, not in a browser; fires the next time the agent processes a ticket; can read, modify or destroy all data on that server, according to the advisory. A statistics strip reads 8.6 CVSS 4.0 High, PR:H high privileges required, UI:N no user interaction, C:H I:H A:H all three impacts high, and 0.28 percent EPSS on 29 October 2026. Three flags below read Affected: Zammad up to and including 7.1.1; Fixed: 7.1.2, released 4 August 2026; Stated remedy: upgrade, no workaround published. A closing panel notes that the advisory publishes no proof of concept and that the regression spec in the fix commit is the clearest public description of the bypass. A footer says hosted instances were already patched and self-hosted installations must reach 7.1.2. The OrcaRouter logo is composited in the bottom-right corner.

L’exigence de privilège mérite un examen plus attentif que ne le suggère le vecteur. PR:H signifie que l’attaquant doit disposer d’un accès important pour que la faille soit exploitable, et ici cet accès correspond à l’autorisation admin.ai_agent dont la documentation de Zammad indique qu’elle est nécessaire pour utiliser les AI Agents. Dans un centre d’assistance, il s’agit souvent d’un responsable de l’équipe de service qui ajuste les catégoriseurs, les étiqueteurs et les extracteurs de texte — pas nécessairement de la personne qui administre le serveur. La formulation de l’avis lui-même, « un administrateur disposant de l’autorisation de créer ou de modifier des AI Agents », est plus étroite que « n’importe qui » et plus large que « root ». Si une mise à niveau ne peut pas être effectuée immédiatement, limiter le nombre de personnes qui détiennent cette autorisation réduit l’ensemble des personnes capables d’atteindre ce chemin de code ; il s’agit d’une déduction tirée du vecteur et de la documentation, pas d’un correctif publié par l’éditeur.

Aucun des documents principaux ne place un modèle de langage dans le chemin d'exploitation. La commande s'exécute au sein du processus Ruby de Zammad lorsque la configuration de l'agent est rendue ; rien dans l'avis, le commit ou la note de version ne décrit le modèle produisant la charge utile. La fonctionnalité AI Agent fournit le champ modifiable par l'administrateur et traité par le moteur de modèles, et l'IA est la surface plutôt que le mécanisme. C'est le schéma que le dossier met en évidence : la définition de l'agent — ses instructions, modèles et filtres — est une configuration exécutable, modifiée par des personnes dont le métier est le support, et non la revue de sécurité.

Le correctif de Zammad est proportionné et terne : un changement de méthode, deux tests de régression et une montée de version qui comble dix-sept autres failles en même temps que celle-ci. Ce qu’il faut retenir, c’est le modèle d’exposition. Un helpdesk qui permet à un responsable du support de définir un agent permet aussi à ce responsable d’écrire quelque chose que le serveur exécutera, et la seule chose qui sépare les deux est un filtre qui doit être juste pour chaque copie imbriquée de la syntaxe qu’il supprime.