Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction — CVE-2025-59059: Fehlzugeschriebene RCE-Korrektur der statischen Analyse in Apache Ranger | Kitploit
Tools/GitHubGitHub/pl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction
Statische AnalyseSchwachstellenanalyseCode-AnalyseExploitationWebsicherheitLernen & Bildung
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: Fehlzugeschriebene RCE-Korrektur der statischen Analyse in Apache Ranger

Repository anzeigen
15vor 5 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2025-59059: Fälschlich zugeordnete RCE in Apache Ranger – eine Korrektur

CVE: CVE-2025-59059
Betroffene Versionen: Apache Ranger <= 2.7.0
Behoben in: Apache Ranger 2.8.0
CVSS (offiziell): 9,8 Kritisch
Tatsächlicher Schweregrad (argumentiert): ~6,0 Mittel – siehe Analyse unten


Vorwort

Dieser Artikel beschreibt keinen neuen Exploit oder einen funktionierenden PoC. Es geht darum, die Fehler in der öffentlichen Offenlegung von CVE-2025-59059 zu korrigieren – konkret zwei Dinge: Die falsche Klasse wurde als anfällige Komponente genannt, und der CVSS-Score spiegelt nicht die tatsächlichen Einschränkungen der Ausnutzbarkeit wider. Alles basiert auf statischer Codeanalyse des Apache Ranger 2.7.0-Quellcodes und dem Patch-Diff, der in 2.8.0 eingeflossen ist.


Was das Advisory sagt

Das offizielle Advisory lautet:

„Remote Code Execution Vulnerability in NashornScriptEngineCreator is reported in Apache Ranger versions <= 2.7.0."

Dies ist falsch oder zumindest irreführend. NashornScriptEngineCreator ist nicht die anfällige Klasse. Wenn überhaupt, ist sie die besser gehärtete der beiden Nashorn-bezogenen Komponenten im Codebase – dazu später mehr.


Hintergrund: Nashorn in Apache Ranger

Apache Ranger verwendet JavaScript-Ausdrücke, um zeilenbasierte Filterrichtlinien auszuwerten. Dabei handelt es sich um Regeln, die entscheiden, ob ein bestimmter Benutzer Zugriff auf einen bestimmten Datensatz in einem Dataset erhält. Um diese Ausdrücke auf der JVM auszuführen, bindet Ranger eine JavaScript-Engine ein. In Versionen <= 2.7.0 ist das Nashorn, Oracles integrierte JS-Engine, die mit JDK 8 bis 14 ausgeliefert wurde.

Ein Punkt, den das Advisory völlig auslässt – und der für die Eingrenzung der Auswirkungen sehr wichtig ist – ist, dass jdk.nashorn.api.scripting.NashornScriptEngineFactory überhaupt nicht zum Ranger-Quellcode gehört. Es ist ein JDK-Bestandteil. Es war in JDK 8 enthalten, in JDK 11 als veraltet markiert und in JDK 15 vollständig entfernt. Diese Sicherheitslücke ist daher nur ausnutzbar, wenn Ranger auf JDK 8 bis 14 läuft. Alles auf JDK 15+ ist nicht betroffen, weil Nashorn dort einfach nicht existiert und ScriptEngineUtil stillschweigend auf GraalJS oder JavaScriptEngineCreator zurückfällt.

Zwei Klassen in Ranger verwenden Nashorn. Sie behandeln es sehr unterschiedlich.


Die beiden Nashorn-bezogenen Klassen

1. NashornScriptEngineCreator – die genannte, aber sicherere

Lokation:

root@kitploit:~
agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
root@kitploit:~
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;
        }
    }
}

Diese Klasse unternimmt tatsächlich drei Dinge, um die Engine zu härten:

  • --no-java – unterbindet direkten Zugriff auf den Namensraum java.* aus Skripten
  • --no-syntax-extensions – deaktiviert nicht standardmäßige Nashorn-Syntax
  • RangerClassFilter – blockiert allen Zugriff auf Java-Klassen auf ClassFilter-Ebene, gibt für alles false zurück

Ist es kugelsicher? Nein. Nashorn-ClassFilter-Umgehungen existieren über Reflektionsketten und java.lang.invoke-Tricks. Aber es ist deutlich stärker eingeschränkt als das, was wir in der anderen Klasse finden.


2. RecordFilterJavaScript – die tatsächlich anfällige Klasse

Lokation:

root@kitploit:~
plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
root@kitploit:~
public class RecordFilterJavaScript {

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

        boolean containsMalware(String filterExpr) {
            // prüft nur auf diese eine bestimmte Zeichenkette
            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...");
        }

        // instanziiert Nashorn direkt – ohne --no-java, ohne --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);
        ...
    }
}

Vergleicht man dies mit NashornScriptEngineCreator, ist der Unterschied ziemlich offensichtlich:

  • Kein --no-java-Flag – der Namensraum java.* ist für Skripte vollständig geöffnet
  • Kein --no-syntax-extensions
  • Die einzige „Sicherheit" ist eine einzige Zeichenkettenprüfung: filterExpr.contains("this.engine")
  • filterExpr wird direkt in das Skript concateniert, das Nashorn auswertet

Da --no-java nicht übergeben wird, ist der Namensraum java.* vollständig zugänglich. Man braucht überhaupt keine Umgehungstechnik:

root@kitploit:~
var runtime = java.lang.Runtime.getRuntime();
runtime.exec("id");

Kein this.engine irgendwo darin. Die Blacklist ist für diesen Angriffspfad völlig irrelevant.

Interessant ist, dass die Entwickler offenbar mindestens ein Umgehungsmuster kannten. Die Testdatei TestRecordFilterJavaScript.java enthält Folgendes:

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

Dieser Test existiert, um zu bestätigen, dass this.engine blockiert wird. Was nicht blockiert wurde, ist der direkte java.*-Pfad, der überhaupt kein this.engine benötigt.


Der Einstiegspunkt

RecordFilterJavaScript.filterRow() wird nur von einer Stelle aufgerufen:

root@kitploit:~
plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java
root@kitploit:~
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 stammt aus result.getFilterExpr(), das ist der JavaScript-Ausdruck, der in einer Ranger-Zeilenfilterrichtlinie gespeichert ist. Ein Angreifer mit Richtlinien-Admin-Rechten kann diesen Ausdruck auf alles setzen, was er möchte. Wenn dann ein Benutzer auf eine Ressource zugreift, die von dieser Richtlinie gesteuert wird, feuert hasAccessToRecord(), holt filterExpr aus dem Richtlinienspeicher, und filterRow() übergibt es an Nashorn – praktisch ohne Sandboxing.

Angriffskette:

root@kitploit:~
Richtlinien-Admin-Zugriff
       |
       v
Erstellen/Ändern einer Zeilenfilterrichtlinie für eine NestedStructure-Ressource
       |
       v
filterExpr gesetzt auf: java.lang.Runtime.getRuntime().exec("...")
       |
       v
Jeder Benutzer greift auf die Ressource zu → hasAccessToRecord() wird ausgelöst
       |
       v
filterExpr gelangt in filterRow() → Nashorn wertet es aus → RCE

Der Patch-Diff

Der Fix wird als RANGER-4076: Remove Nashorn Script Engine verfolgt, committet am 8. Dezember 2025 von Kishor Gollapalliwar. Entnommen aus dem Apache-Mailinglisten-Commit-Archiv. Drei Dateien geändert, 27 Einfügungen, 81 Löschungen.

root@kitploit:~
commit 923a8473de2985cd389d45062cd4717d5ca13235
Author: Kishor Gollapalliwar
AuthorDate: Mon Dec 8 14:55:56 2025 +0530

    RANGER-4076: Remove Nashorn Script Engine

 .../plugin/util/NashornScriptEngineCreator.java    | 67 ----------------------
 .../ranger/plugin/util/ScriptEngineUtil.java       |  7 +--
 .../authorizer/RecordFilterJavaScript.java         | 34 ++++++++---
 3 files changed, 27 insertions(+), 81 deletions(-)

Datei 1: NashornScriptEngineCreator.java komplett gelöscht

root@kitploit:~
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
deleted file mode 100644
index b890fe85d..000000000
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.apache.ranger.plugin.util;
-
-import jdk.nashorn.api.scripting.ClassFilter;
-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
-
-public class NashornScriptEngineCreator implements ScriptEngineCreator {
-
-    private static final String[] SCRIPT_ENGINE_ARGS = new String[] {
-        "--no-java", "--no-syntax-extensions"
-    };
-    private static final String ENGINE_NAME = "NashornScriptEngine";
-
-    @Override
-    public ScriptEngine getScriptEngine(ClassLoader clsLoader) {
-        ScriptEngine ret = null;
-        if (clsLoader == null) {
-            clsLoader = getDefaultClassLoader();
-        }
-        try {
-            NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
-            ret = factory.getScriptEngine(SCRIPT_ENGINE_ARGS, clsLoader, RangerClassFilter.INSTANCE);
-        } catch (Throwable t) {
-            LOG.debug("NashornScriptEngineCreator.getScriptEngine(): failed to create engine type {}", ENGINE_NAME, t);
-        }
-        return ret;
-    }
-
-    private static class RangerClassFilter implements ClassFilter {
-        static final RangerClassFilter INSTANCE = new RangerClassFilter();
-
-        @Override
-        public boolean exposeToScripts(String className) {
-            LOG.warn("script blocked: attempt to use Java class {}", className);
-            return false;
-        }
-    }
-}

Datei 2: ScriptEngineUtil.java – Nashorn aus der Engine-Creator-Kette entfernt

root@kitploit:~
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ScriptEngineUtil.java
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ScriptEngineUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ScriptEngineUtil.java
@@ -28,10 +28,9 @@
 public class ScriptEngineUtil {

-    private static final String   SCRIPT_ENGINE_CREATOR_NASHHORN =
-        "org.apache.ranger.plugin.util.NashornScriptEngineCreator";
     private static final String   SCRIPT_ENGINE_CREATOR_GRAAL    =
         "org.apache.ranger.plugin.util.GraalScriptEngineCreator";
     private static final String   SCRIPT_ENGINE_CREATOR_JS       =
         "org.apache.ranger.plugin.util.JavaScriptEngineCreator";
-    private static final String[] SCRIPT_ENGINE_CREATORS = new String[] {
-        SCRIPT_ENGINE_CREATOR_NASHHORN,
-        SCRIPT_ENGINE_CREATOR_GRAAL,
-        SCRIPT_ENGINE_CREATOR_JS
-    };
+    private static final String[] SCRIPT_ENGINE_CREATORS = new String[] {
+        SCRIPT_ENGINE_CREATOR_GRAAL,
+        SCRIPT_ENGINE_CREATOR_JS
+    };

@@ -108,9 +107,7 @@ private static void initScriptEngineCreator(String serviceType) {
         } catch (Throwable t) {
             boolean logWarn;

-            if (creatorClsName.equals(SCRIPT_ENGINE_CREATOR_NASHHORN)) {
-                logWarn = JVM_MAJOR_CLASS_VERSION < JVM_MAJOR_CLASS_VERSION_JDK15;
-            } else if (creatorClsName.equals(SCRIPT_ENGINE_CREATOR_GRAAL)) {
+            if (creatorClsName.equals(SCRIPT_ENGINE_CREATOR_GRAAL)) {
                 logWarn = JVM_MAJOR_CLASS_VERSION >= JVM_MAJOR_CLASS_VERSION_JDK15;
             } else {
                 logWarn = true;

Datei 3: RecordFilterJavaScript.java – der eigentliche Fix

Hier findet die eigentliche sicherheitsrelevante Änderung statt. Der direkte NashornScriptEngineFactory-Aufruf wird durch GraalJS ersetzt, und SecurityFilter verliert seine ClassFilter-Rolle vollständig – wird zu einer einfachen Klasse degradiert, die nur noch die Zeichenkettenprüfung behält.

root@kitploit:~
diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
--- a/plugin-nestedstructure/.../RecordFilterJavaScript.java
+++ b/plugin-nestedstructure/.../RecordFilterJavaScript.java
@@ -18,13 +18,16 @@
-import jdk.nashorn.api.scripting.ClassFilter;
-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngineManager;
+import java.util.HashMap;
+import java.util.Map;

@@ -54,8 +57,25 @@
         if (securityFilter.containsMalware(filterExpr)) {
             throw new MaskingException("cannot process filter expression...");
         }

-        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
-        ScriptEngine engine = factory.getScriptEngine(securityFilter);
+        ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
+        ScriptEngineManager mgr = new ScriptEngineManager(clsLoader);
+        ScriptEngine engine = mgr.getEngineByName("graal.js");
+
+        if (engine != null) {
+            try {
+                Map<String, Boolean> graalVmConfigs = new HashMap<>();
+                graalVmConfigs.put("polyglot.js.allowHostAccess", Boolean.TRUE);
+                graalVmConfigs.put("polyglot.js.nashorn-compat", Boolean.TRUE);
+
+                Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+                bindings.putAll(graalVmConfigs);
+                engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
+            } catch (Throwable t) {
+                logger.debug("RecordFilterJavaScript.filterRow(): failed to create engine type {}", "graal.js", t);
+            }
+        }

@@ -83,12 +103,8 @@
-    static class SecurityFilter implements ClassFilter {
-        @Override
-        public boolean exposeToScripts(String s) {
-            return false;
-        }
-
+    static class SecurityFilter {
         boolean containsMalware(String filterExpr) {
             return filterExpr.contains("this.engine");
         }
     }

Einige erwähnenswerte Punkte aus diesem Diff:

  • SecurityFilter ist kein ClassFilter mehr – verliert seinen Engine-Level-Hook und wird zu einer einfachen Klasse, die nur noch die Zeichenkettenprüfung behält
  • Nashorn-Imports sind entfernt, ersetzt durch ScriptEngineManager
  • GraalJS läuft im nashorn-compat-Modus für Abwärtskompatibilität mit bestehenden Richtlinienausdrücken
  • polyglot.js.allowHostAccess ist auf true gesetzt – dies ist ein Kompromiss für die Abwärtskompatibilität und verlässt sich auf GraalJS eigenes Sandboxing anstelle eines ClassFilter. Es lohnt sich, dies im Auge zu behalten, wenn einem die Qualität des Fixes wichtig ist.

Der Patch macht deutlich, dass RecordFilterJavaScript das eigentliche Sicherheitsziel war. Das Löschen von NashornScriptEngineCreator war eine Bereinigung, nicht der Fix.


Warum der CVE die falsche Klasse nannte

Ehrlich gesagt ist es nicht schwer zu verstehen, wie das passieren konnte. NashornScriptEngineCreator befindet sich direkt in agents-common, ist die offensichtlichste Nashorn-Klasse im gesamten Codebase, und ein einfaches Grep nach Nashorn würde sie sofort aufspüren. RecordFilterJavaScript hingegen lebt in plugin-nestedstructure, einem separaten Submodul, und der Klassenname enthält keinerlei Hinweis auf Nashorn. Wenn jemand eine schnelle Sichtung durchführt, ohne den Code-Pfad tatsächlich zu verfolgen, würde er wahrscheinlich auf NashornScriptEngineCreator stoßen und dort aufhören.

Das scheint hier passiert zu sein. Die anfällige Klasse und die Klasse, die im Advisory genannt wurde, sind zwei verschiedene Dinge.


Warum der CVSS 9,8 nicht haltbar ist

Eine 9,8 impliziert netzwerkerreichbar, keine Authentifizierung erforderlich, keine Benutzerinteraktion nötig. Die Realität sieht ganz anders aus:

FaktorRealität
Authentifizierungerfordert Richtlinien-Admin-Rechte in Ranger
Plugin-Erfordernisplugin-nestedstructure ist nicht standardmäßig aktiviert
JDK-Einschränkungnur auf JDK 8–14 ausnutzbar, JDK 15+ ist nicht betroffen
NetzzugänglichkeitFOFA-Fingerprinting ergab ~35 öffentlich zugängliche Ranger-Instanzen

Nichts davon spiegelt sich im Advisory wider. Um dies tatsächlich auszunutzen, benötigt man Richtlinien-Admin-Zugriff, was eine erhebliche Privilegienstufe innerhalb einer Ranger-Bereitstellung darstellt. Dies ist keine nicht authentifizierte RCE. Unter Berücksichtigung der Authentifizierungsanforderung und des nicht standardmäßigen Plugins wäre ein Wert im Bereich 6,0–7,0 ein ehrlicherer Score.


Zusammenfassung

Behauptung im AdvisoryTatsächlicher Befund
Anfällige KlasseNashornScriptEngineCreatorRecordFilterJavaScript
AngriffsartNicht authentifizierte RCEAuthentifizierte RCE (Richtlinien-Admin erforderlich)
Betroffenes JDKNicht spezifiziertNur JDK 8–14
Erforderliches PluginNicht spezifiziertplugin-nestedstructure (nicht standard)
CVSS9,8 Kritisch~6,0 Mittel (argumentiert)
InternetzugänglichkeitNicht spezifiziert~35 Instanzen (FOFA)

Die Schwachstelle ist real, und ein Upgrade auf 2.8.0 ist der richtige Schritt. Aber das Advisory nennt die falsche Klasse, und der Schweregrad-Score spiegelt nicht die tatsächlich erforderlichen Bedingungen für die Ausnutzung wider.


Referenzen

  • Apache Ranger 2.8.0 Release: https://ranger.apache.org/download.html
  • Patch-Commit (RANGER-4076): https://gitbox.apache.org/repos/asf/ranger.git
  • CVE-Eintrag: https://www.cve.org/CVERecord?id=CVE-2025-59059
  • Apache-Mailingliste-Thread: https://lists.apache.org/thread/z47q86rho80390lf2qcmoc2josvs0gtv
Tool herunterladen