Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction — CVE-2025-59059: Apache Ranger 静的解析修正における誤帰属の RCE | Kitploit
ツール/GitHubGitHub/pl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction
静的分析脆弱性分析コード分析エクスプロイトウェブセキュリティ学習と教育
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: Apache Ranger 静的解析修正における誤帰属の RCE

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
リポジトリを見る
155ヶ月前未レビュー
共有

CVE-2025-59059: Apache Ranger における誤った帰属の RCE — 訂正

CVE: CVE-2025-59059
影響を受けるバージョン: Apache Ranger <= 2.7.0
修正版: Apache Ranger 2.8.0
CVSS(公式): 9.8 Critical
実際の深刻度(主張): ~6.0 Medium — 分析は以下を参照


はじめに

この記事は新たなエクスプロイトや動作する PoC についてのものではない。ここでの目的は、CVE-2025-59059 に関する公開情報の誤りを訂正することだ。具体的には2点: 脆弱性コンポーネントとして誤ったクラスが指定されたこと、CVSS スコアが実際の悪用可能性の制約を反映していないこと。ここで述べる内容はすべて、Apache Ranger 2.7.0 ソースコードと 2.8.0 に取り込まれたパッチ差分の静的コード解析に基づく。


アドバイザリの内容

公式アドバイザリには次のように記載されている:

"NashornScriptEngineCreator のリモートコード実行の脆弱性が Apache Ranger バージョン <= 2.7.0 で報告されています。"

これは誤りであり、少なくとも誤解を招く。NashornScriptEngineCreator は脆弱性のあるクラスではない。どちらかと言えば、コードベース内の Nashorn 関連コンポーネントのうち、より堅牢化されている方だ — これについては後述する。


背景: Apache Ranger における Nashorn

Apache Ranger は、行レベルフィルターポリシーを評価するために JavaScript 式を使用する。これらは、特定のユーザーがデータセット内の特定のレコードにアクセスできるかどうかを決定するルールだ。それらの式を JVM 上で実際に実行するために、Ranger は JavaScript エンジンを組み込んでいる。バージョン <= 2.7.0 では、そのエンジンは Nashorn だ。これは JDK 8 から 14 に同梱されていた Oracle の組み込み JS エンジンである。

アドバイザリが完全に省略している点 — そして影響範囲の評価において非常に重要な点 — は、jdk.nashorn.api.scripting.NashornScriptEngineFactory が Ranger のソースコードには一切含まれていないことだ。これは JDK の組み込み機能である。JDK 8 に含まれ、JDK 11 で非推奨となり、JDK 15 で完全に削除された。つまり、この脆弱性に到達できるのは JDK 8 から 14 で Ranger を実行している場合のみだ。JDK 15+ では Nashorn が存在しないため影響を受けず、 は黙って GraalJS または にフォールバックする。

ScriptEngineUtil
JavaScriptEngineCreator

Ranger 内で Nashorn を使用するクラスは2つあり、その扱いは大きく異なる。


Nashorn 関連の 2 つのクラス

1. NashornScriptEngineCreator — 名前が挙げられたが安全な方

場所:

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;
        }
    }
}

このクラスは実際にはエンジンを堅牢化するために3つのことを行っている:

  • --no-java — スクリプト内から java.* 名前空間への直接アクセスを遮断
  • --no-syntax-extensions — 標準外の Nashorn 構文を無効化
  • RangerClassFilter — ClassFilter レベルで全ての Java クラスアクセスをブロックし、すべてに対して false を返す

完璧か? 否。Nashorn の ClassFilter バイパスは、リフレクションチェーンや java.lang.invoke のトリックを通じて存在する。しかし、もう一方のクラスにあるものと比べれば、意味のあるレベルでロックダウンされている。


2. RecordFilterJavaScript — 実際の脆弱性のあるクラス

場所:

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) {
            // 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);
        ...
    }
}

これを NashornScriptEngineCreator と比較すると、その違いは明らかだ:

  • --no-java フラグなし — java.* 名前空間はスクリプトに対して完全に開放されている
  • --no-syntax-extensions なし
  • 唯一の「セキュリティ」は1つの文字列チェックのみ: filterExpr.contains("this.engine")
  • filterExpr は Nashorn が評価するスクリプトに直接連結される

--no-java が渡されていないため、java.* 名前空間には完全にアクセスできる。バイパス技術は一切必要ない:

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

この中に this.engine はどこにもない。ブラックリストはこの攻撃経路に対して完全に無関係だ。

興味深いのは、開発者が少なくとも1つのバイパスパターンを明確に認識していたことだ。テストファイル TestRecordFilterJavaScript.java には次の記述がある:

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

このテストは this.engine がブロックされることを確認するために存在する。ブロックされなかったのは、this.engine を一切必要としない直接の java.* パスだ。


エントリーポイント

RecordFilterJavaScript.filterRow() が呼び出される場所は1箇所のみ:

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 は result.getFilterExpr() から取得される。これは Ranger の行フィルターポリシーに保存されている JavaScript 式だ。ポリシー管理者権限を持つ攻撃者は、その式を任意の内容に設定できる。その後、任意のユーザーがそのポリシーの適用対象となるリソースにアクセスすると、hasAccessToRecord() が実行され、ポリシーストアから filterExpr を取得し、filterRow() がそれをほぼサンドボックスなしで Nashorn に渡す。

攻撃チェーン:

root@kitploit:~
ポリシー管理者権限
       |
       v
nestedstructure リソースに対する行フィルターポリシーを作成/変更
       |
       v
filterExpr に設定: java.lang.Runtime.getRuntime().exec("...")
       |
       v
任意のユーザーがリソースにアクセス → hasAccessToRecord() が実行される
       |
       v
filterExpr が filterRow() に流入 → Nashorn が評価 → RCE

パッチ差分

この修正は RANGER-4076: Remove Nashorn Script Engine として追跡されており、2025年12月8日に Kishor Gollapalliwar 氏によってコミットされた。Apache メーリングリストのコミットアーカイブから取得した。変更ファイルは3つ、挿入27行、削除81行。

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(-)

ファイル1: NashornScriptEngineCreator.java 完全削除

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;
-        }
-    }
-}

ファイル2: ScriptEngineUtil.java エンジン生成チェーンから Nashorn を削除

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;

ファイル3: RecordFilterJavaScript.java 本当の修正

ここが実際のセキュリティ変更箇所だ。直接の NashornScriptEngineFactory 呼び出しは GraalJS に置き換えられ、SecurityFilter は ClassFilter としての役割を完全に失い、文字列チェックのみを残した通常のクラスに格下げされている。

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");
         }
     }

この差分から指摘しておく価値のある点がいくつかある:

  • SecurityFilter はもはや ClassFilter ではない — エンジンレベルのフックを失い、文字列チェックだけが残った通常のクラスになる
  • Nashorn のインポートは削除され、ScriptEngineManager に置き換えられた
  • GraalJS は既存のポリシー式との後方互換性のため nashorn-compat モードで動作する
  • polyglot.js.allowHostAccess は true に設定されている — これは後方互換性のためのトレードオフであり、ClassFilter ではなく GraalJS 自身のサンドボックスに依存している。修正の品質を気にするなら注目しておく価値がある

このパッチは、RecordFilterJavaScript が実際のセキュリティ修正対象であったことを明確に示している。NashornScriptEngineCreator の削除は整理整頓であって、修正ではない。


なぜ CVE は誤ったクラスを指定したのか

正直なところ、どうしてこうなったかは理解しやすい。NashornScriptEngineCreator は agents-common 内にあり、コードベース全体で最も明白に Nashorn と名付けられたクラスであり、Nashorn を基本的な grep で検索すれば即座に表面化する。一方、RecordFilterJavaScript は別のサブモジュールである plugin-nestedstructure 内にあり、クラス名には Nashorn を連想させるものは何もない。コードパスを実際に追わずに簡単なトリアージを行えば、おそらく NashornScriptEngineCreator にたどり着いてそこで止まるだろう。

ここで起きたのはまさにそれのようだ。脆弱性のあるクラスと、アドバイザリで名前が挙げられたクラスは別物だ。


なぜ CVSS 9.8 が成立しないのか

9.8 は、ネットワークから到達可能、認証不要、ユーザー操作不要を意味する。現実はかなり異なる:

要素現実
認証Ranger のポリシー管理者権限が必要
プラグイン要件plugin-nestedstructure はデフォルトでは有効化されていない
JDK 制約JDK 8–14 でのみ悪用可能、JDK 15+ は影響なし
ネットワーク露出FOFA フィンガープリンティングで公開された Ranger インスタンスは約35件

これらのいずれもアドバイザリには反映されていない。実際に悪用するにはポリシー管理者アクセスが必要であり、これは Ranger デプロイメント内では相当高い権限レベルだ。これは認証なしの RCE ではない。認証要件と非デフォルトのプラグインを考慮すると、6.0〜7.0 程度がより誠実なスコアだろう。


まとめ

アドバイザリの主張実際の調査結果
脆弱性のあるクラスNashornScriptEngineCreatorRecordFilterJavaScript
攻撃タイプ認証なし RCE認証済み RCE (ポリシー管理者が必要)
影響を受ける JDK指定なしJDK 8–14 のみ
必要なプラグイン指定なしplugin-nestedstructure (非デフォルト)
CVSS9.8 Critical~6.0 Medium (主張)
インターネット露出指定なし約35インスタンス (FOFA)

脆弱性は実在し、2.8.0 へのアップグレードが正しい対応だ。しかし、アドバイザリはクラス名を誤っており、深刻度スコアも実際に悪用するために必要な条件を反映していない。


参照

  • Apache Ranger 2.8.0 リリース: https://ranger.apache.org/download.html
  • パッチコミット (RANGER-4076): https://gitbox.apache.org/repos/asf/ranger.git
  • CVE エントリ: https://www.cve.org/CVERecord?id=CVE-2025-59059
  • Apache メーリングリストのスレッド: https://lists.apache.org/thread/z47q86rho80390lf2qcmoc2josvs0gtv
ツールをダウンロード