Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction — CVE-2025-59059 : Correction d'analyse statique pour une RCE mal attribuée dans Apache Ranger | Kitploit
Outils/GitHubGitHub/pl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction
Analyse StatiqueAnalyse des VulnérabilitésAnalyse de CodeExploitationSécurité WebApprentissage et Éducation
GitHubpl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction

CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction

CVE-2025-59059 : Correction d'analyse statique pour une RCE mal attribuée dans Apache Ranger

Voir le dépôt
26il y a 5 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2025-59059 : RCE mal attribuée dans Apache Ranger — une correction

CVE : CVE-2025-59059
Versions affectées : Apache Ranger <= 2.7.0
Corrigé dans : Apache Ranger 2.8.0
CVSS (officiel) : 9.8 Critique
Sévérité réelle (argumentée) : ~6.0 Moyen — voir analyse ci-dessous


Préface

Ce billet ne parle pas d'un nouvel exploit ni d'un PoC fonctionnel. Le but ici est de corriger ce qui cloche dans la divulgation publique de CVE-2025-59059, plus précisément deux choses : la mauvaise classe a été désignée comme composant vulnérable, et le score CVSS ne reflète pas les contraintes réelles d'exploitabilité. Tout ceci repose sur une analyse statique du code source d'Apache Ranger 2.7.0 et sur le diff du correctif intégré dans 2.8.0.


Ce que dit l'avis

L'avis officiel indique :

« Remote Code Execution Vulnerability in NashornScriptEngineCreator is reported in Apache Ranger versions <= 2.7.0. »

C'est faux, ou du moins trompeur. NashornScriptEngineCreator n'est pas la classe vulnérable. Si quoi que ce soit, c'est la mieux durcie des deux composants liés à Nashorn dans le codebase — comme nous allons le voir.


Contexte : Nashorn dans Apache Ranger

Apache Ranger utilise des expressions JavaScript pour évaluer les politiques de filtrage au niveau des lignes. Ce sont des règles qui déterminent si un utilisateur donné peut accéder à un enregistrement spécifique dans un jeu de données. Pour exécuter ces expressions sur la JVM, Ranger embarque un moteur JavaScript. Dans les versions <= 2.7.0, ce moteur est Nashorn, le moteur JS intégré d'Oracle livré avec les JDK 8 à 14.

Une chose que l'avis omet complètement — et qui compte beaucoup pour évaluer le périmètre d'impact — est que jdk.nashorn.api.scripting.NashornScriptEngineFactory ne fait pas du tout partie du code source de Ranger. C'est un composant intégré au JDK. Il a été inclus dans JDK 8, déprécié dans JDK 11 et totalement supprimé dans JDK 15. Cette vulnérabilité n'est donc exploitable que si vous exécutez Ranger sur un JDK 8 à 14. Tout ce qui tourne sur JDK 15+ n'est pas concerné, car Nashorn n'y existe tout simplement pas, et ScriptEngineUtil retombe silencieusement sur GraalJS ou JavaScriptEngineCreator.

Deux classes de Ranger utilisent Nashorn. Elles le traitent de manière très différente.


Les deux classes liées à Nashorn

1. NashornScriptEngineCreator — la classe nommée mais la plus sûre

située à :

agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
public class NashornScriptEngineCreator implements ScriptEngineCreator {

    private static final String[] SCRIPT_ENGINE_ARGS = new String[] {
        "--no-java", "--no-syntax-extensions"
    };

    @Override
    public ScriptEngine getScriptEngine(ClassLoader clsLoader) {
        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        ret = factory.getScriptEngine(SCRIPT_ENGINE_ARGS, clsLoader, RangerClassFilter.INSTANCE);
        ...
    }

    private static class RangerClassFilter implements ClassFilter {
        @Override
        public boolean exposeToScripts(String className) {
            LOG.warn("script blocked: attempt to use Java class {}", className);
            return false;
        }
    }
}

Cette classe fait en réalité trois choses pour durcir le moteur :

  • --no-java — coupe l'accès direct à l'espace de noms java.* depuis les scripts
  • --no-syntax-extensions — désactive la syntaxe Nashorn non standard
  • RangerClassFilter — bloque tout accès aux classes Java au niveau du ClassFilter, renvoyant false pour tout

Est-ce infaillible ? Non. Des contournements du ClassFilter de Nashorn existent via des chaînes de réflexion et des astuces java.lang.invoke. Mais c'est nettement plus verrouillé que ce que l'on trouve dans l'autre classe.


2. RecordFilterJavaScript — la classe réellement vulnérable

située à :

plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
public class RecordFilterJavaScript {

    static class SecurityFilter implements ClassFilter {
        @Override
        public boolean exposeToScripts(String s) {
            return false;
        }

        boolean containsMalware(String filterExpr) {
            // only checks for this one specific string
            return filterExpr.contains("this.engine");
        }
    }

    public static boolean filterRow(String user, String filterExpr, String jsonString) {
        SecurityFilter securityFilter = new SecurityFilter();

        if (securityFilter.containsMalware(filterExpr)) {
            throw new MaskingException("cannot process filter expression due to security concern...");
        }

        // instantiates Nashorn directly — no --no-java, no --no-syntax-extensions
        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        ScriptEngine engine = factory.getScriptEngine(securityFilter);

        String script = " jsonAttr = JSON.parse(jsonString); " + filterExpr;

        Bindings bindings = engine.createBindings();
        bindings.put("jsonString", jsonString);
        bindings.put("user", user);

        boolean hasAccess = (boolean) engine.eval(script, bindings);
        ...
    }
}

Comparez cela avec NashornScriptEngineCreator et la différence est assez évidente :

  • pas d'option --no-java : l'espace de noms java.* est entièrement ouvert aux scripts
  • pas de --no-syntax-extensions
  • la seule « sécurité » est une vérification de chaîne : filterExpr.contains("this.engine")
  • filterExpr est concaténée directement dans le script que Nashorn évalue

Étant donné que --no-java n'est pas passé, l'espace de noms java.* est entièrement accessible. Aucune technique de contournement n'est nécessaire :

var runtime = java.lang.Runtime.getRuntime();
runtime.exec("id");

Aucun this.engine là-dedans. La liste noire est totalement hors de propos pour ce vecteur d'attaque.

Ce qui est intéressant, c'est que les développeurs connaissaient visiblement au moins un schéma de contournement. Le fichier de test TestRecordFilterJavaScript.java contient ceci :

RecordFilterJavaScript.filterRow("user",
    "this.engine.factory.scriptEngine.eval('java.lang.Runtime.getRuntime().exec(\"/Applications/Spotify.app/Contents/MacOS/Spotify\")')",
    ...);

Ce test existe pour confirmer que this.engine est bloqué. Ce qui n'a pas été bloqué, c'est le chemin direct java.*, qui n'a pas du tout besoin de this.engine.


Le point d'entrée

RecordFilterJavaScript.filterRow() n'est appelé qu'à un seul endroit :

plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java
private boolean hasAccessToRecord(String schema, String user, ..., String jsonString, ...) {
    RangerAccessResult result = plugin.evalRowFilterPolicies(request, null);

    if (result.isRowFilterEnabled()) {
        String filterExpr = result.getFilterExpr();
        ret = RecordFilterJavaScript.filterRow(user, filterExpr, jsonString);
    }
    return ret;
}

filterExpr provient de result.getFilterExpr(). C'est l'expression JavaScript stockée dans une politique de filtre de lignes Ranger. Un attaquant disposant des privilèges d'administrateur de politiques peut définir cette expression comme il le souhaite. Lorsqu'un utilisateur accède ensuite à une ressource régie par cette politique, hasAccessToRecord() se déclenche, récupère filterExpr depuis le stockage de politiques et filterRow() le transmet à Nashorn sans véritable sandbox.

chaîne d'attaque :

Télécharger l’outil