エグゼクティブサマリー
CVE-2025-62593は、Python機械学習ワークロードで広く使われている分散コンピューティングフレームワーク「Ray」に存在する深刻なリモートコード実行の脆弱性です。
この攻撃はDNSリバインディングと、User-Agentに基づくブラウザ判定の欠陥を組み合わせたものです。攻撃者が用意したWebページは、被害者のブラウザを利用してローカルで稼働するポート8265のRay Dashboardにアクセスし、ブラウザリクエストに対する保護をバイパスすることで、Rayの認証情報を必要とせずにJobs APIへアクセスできてしまいます。
細工したRayジョブを送信することで、攻撃者はRayプロセスの権限で任意のコマンドを実行できる可能性があります。これにより、ソースコード、認証情報、学習データ、モデルの成果物、クラウドリソース、内部サービスが露出するおそれがあるほか、リソースの不正利用や横展開(ラテラルムーブメント)も可能になります。
米国のサイバーセキュリティ・インフラセキュリティ庁(CISA)は、実際に悪用が確認されているとして2026年8月17日にKEVカタログへCVE-2025-62593を追加しました。組織はRay 2.52.0以降、できれば2.52.1へのアップグレード、トークン認証の有効化、Ray管理インターフェースへのアクセス制限、そして侵害の兆候がないかの調査を行うべきです。
この脆弱性は重要な教訓を浮き彫りにしています。それはlocalhostが自動的に信頼できるセキュリティ境界になるわけではないということです。特にワークロードを実行できる管理インターフェースにおいてはなおさらです。
Rayとは何か
Rayは、単一の開発者マシンからマルチノードクラスタに至るまで、Pythonアプリケーションと機械学習ワークロードをスケールさせるために設計されたオープンソースの分散コンピューティングフレームワークです。もともとUCバークレーで開発され、現在はAnyscaleとともにRayプロジェクトが保守を行っています。Rayは分散ランタイムを提供しており、開発者は分散実行向けにアプリケーションを一から設計し直すことなく、CPU、GPU、複数のマシンにまたがってPythonワークロードを実行できます。
Rayの中核にはタスク、アクター、オブジェクトという3つの基本的な抽象化があります。タスクはステートレスなPython関数をクラスタ全体で実行できるようにし、アクターはステートフルなワーカープロセスを提供し、オブジェクトは分散ワーカー間でのデータ共有とアクセスを可能にします。またRayはリソーススケジューリングも扱っており、ワークロードがCPU・GPU・メモリといったリソースを要求し、利用可能なノードに割り当てられる仕組みになっています。
このアーキテクチャにより、Rayは幅広いワークロードに活用できます。そのエコシステムには、分散データ処理向けのRay Data、分散モデル学習向けのRay Train、ハイパーパラメータ最適化向けのRay Tune、強化学習向けのRLlib、機械学習・Pythonアプリケーションのデプロイとスケーリング向けのRay Serveが含まれます。Rayはローカル環境、クラウドインフラ、物理・仮想マシン、Kubernetes上で動作します。
基本的なデプロイは、開発者のワークステーション上で以下のコマンドから始められます。pip install ray
その後、Pythonからローカルのインスタンスを初期化するか、Ray headノードとして起動できます。クラスタ構成では、headノードがクラスタ全体を調整し、workerノードがタスクやアクターの実行に使われる計算リソースを提供します。これにより、同じアプリケーションをローカルの開発環境から、CPU・GPU・メモリ・ストレージ容量が大幅に増強された分散環境へと移行させることができます。
Ray Dashboardと管理API
Rayは、アプリケーションの監視、クラスタリソースの確認、ジョブの閲覧、分散ワークロードのトラブルシューティングを行うためのWebベースのDashboardも提供しています。標準的なRayデプロイでは通常、DashboardはTCPポート8265で公開されます。実際、Kubernetesの公式ドキュメントでも、Ray headサービスへのアクセスをフォワーディングする際にポート8265が使われています。
DashboardはRayを単に受動的に監視するインターフェースにとどまりません。RayはHTTP APIを公開しており、アプリケーションやオペレーターが稼働中のクラスタとやり取りできるようになっています。これにはRayジョブの投入・管理の仕組みも含まれます。これは重要なセキュリティ境界です。というのも、Rayのインストール環境は実質的に分散型のコード実行環境であり、クラスタに投入されたワークロードはRayワーカー上でPythonアプリケーションやタスクとして実行されることを前提としているためです。
この点は、CVE-2025-62593を分析するうえで重要です。脆弱なコンポーネントは、単に攻撃者が限定的な機能にアクセスできるだけの一般的なWebアプリケーションではありません。Rayのジョブ管理機能が悪用されると、直接的に分散実行レイヤーへと侵入されるおそれがあります。攻撃者が悪意あるジョブの投入に成功すれば、その結果として実行されるコードはRayプロセスのセキュリティコンテキスト内で動作し、ホスト、そのファイル、認証情報、ネットワーク接続、その他クラスタで利用可能なリソースにアクセスできる可能性があります。
なぜRayの侵害は単一アプリの侵害にとどまらないのか
Rayのデプロイは、単独で孤立したアプリケーションであることはめったにありません。実際の環境では、機密性の高い開発インフラや高価値な機械学習リソースのすぐそばに配置されていることがあります。侵害されたRayノードは、学習用データセット、モデルのチェックポイント、ソースコード、クラウドの認証情報、内部サービス、GPU、他のクラスタノードなどにアクセスできる可能性があります。
これにより、いくつかの異なるセキュリティ境界が生じます。
| 信頼境界 | 含まれる可能性のあるもの | 侵害が重要な理由 |
|---|---|---|
| 開発者のワークステーション | ソースコード、SSHキー、クラウドの認証情報、ローカルのデータベースや設定ファイル | 開発者やML技術者のワークステーションでRCEが成立すると、攻撃者は開発環境への足がかりを得る可能性があります。 |
| Rayアプリケーション環境 | 投入されたジョブ、依存関係、ランタイム環境、ログ、アプリケーションコード | ワークロードを制御できる攻撃者は、実行環境に悪意あるコードや依存関係を持ち込める可能性があります。 |
| Rayのheadノード・workerノード | CPU/GPUリソース、モデルのチェックポイント、データセット、実行中のワークロード | 侵害されると、データ窃取、不正な演算、モデルの改ざん、暗号資産マイニングなどにつながる可能性があります。 |
| クラウドインフラ | IAM認証情報、オブジェクトストレージ、メタデータサービス、その他のクラウドリソース | 認証情報やメタデータエンドポイントにアクセス可能な場合、侵害されたワークロードがクラウドアカウントやインフラ全体の侵害につながる経路になる可能性があります。 |
| 内部ネットワーク | データベース、内部API、サービス、追加の計算クラスタ | 侵害されたRayホストが、インターネットに直接公開されていないシステムへの攻撃の足がかり(ピボットポイント)になる可能性があります。 |
したがって、このセキュリティ上の影響はRayプロセス自体をはるかに超えて及びます。Rayは分散ワークロードを実行するために設計されているため、その制御インターフェースやジョブ投入インターフェースが侵害されると、開発者やデータサイエンティストが本番ワークロードのために信頼している計算環境そのものに、攻撃者がアクセスできてしまう可能性があります。
このアーキテクチャこそが、CVE-2025-62593を特に重大なものにしています。この脆弱性は、ブラウザ経由の攻撃経路と、分散ワークロードを起動できるサービスを組み合わせることで、一見ローカルの開発用インターフェースに見えるものを、基盤となるホスト上での任意コード実行への経路に変えてしまうのです。
影響を受けるバージョンと修正済みバージョン
GitHubのセキュリティアドバイザリでは、2.52.0より前のRay pipパッケージのすべてのバージョンが影響を受けるとされています。部分的なパッチは存在せず、修正は2.52.0で行われ、2.52.1でさらに強化されました。
| コンポーネント | 影響を受けるバージョン | 修正済みバージョン |
|---|---|---|
| ray PyPIパッケージ | 2.52.0未満 | 2.52.0以降(多層防御の観点からは2.52.1が望ましい) |
| Ray dashboard | 2.52.0での強化以前のすべてのバージョン | 2.52.0でブラウザリクエストの保護を強化 |
| Ray Jobs API | 旧バージョンではデフォルトで認証なし | 2.52.0でトークン認証が利用可能(デフォルトでは無効、有効化が必要) |
深刻度スコアに関する補足:GitHubがCNAとして割り当てたCVSS 4.0のスコアは9.4(緊急)です。NVDのCVSS 3.1のスコアは8.8(重要)です。いずれもネットワーク経由での到達可能性、低い攻撃複雑度、機密性・完全性・可用性への高い影響を反映しています。両者の差異は一部評価手法によるものであり、CVSS 4.0はブラウザ起点の攻撃をより深刻に扱う傾向があります。
根本原因:ブラウザとDNSリバインディングを介したコードインジェクション
CVE-2025-62593は、単一のコーディングミスというよりも、複数のセキュリティ上の前提が組み合わさった結果生じています。脆弱なバージョンのRayでは、Dashboardがブラウザ発のステート変更リクエストを制限するためにUser-Agentに基づくブラウザ判定に依存していた一方で、重要なジョブ投入機能は認証なしでアクセス可能なままでした。そこにDNSリバインディングが加わることで、攻撃者が用意したWebページが被害者のlocalhost上で稼働するRayサービスに到達する経路が生まれました。

この攻撃は次の4つの条件に依存しています。
- 認証なしのジョブ投入 — 影響を受けるバージョンでは、Rayは/api/jobs/エンドポイントを認証なしで公開していました。
- 不十分なブラウザ判定 — RayはUser-Agentヘッダーが「Mozilla」で始まるかどうかをチェックすることで、ブラウザ発のPOST・PUTリクエストをブロックしようとしていました。
- User-Agentの改変 — FirefoxとSafariでは、該当するfetch()リクエストにおいてJavaScriptからUser-Agentヘッダーを上書きできるため、このブラウザ判定をバイパスできます。
- DNSリバインディング — 攻撃者のドメインは127.0.0.1:8265や、その他到達可能なRayインスタンスに解決されるよう仕向けられるため、被害者のブラウザがRay Dashboardへの橋渡し役として機能してしまいます。
これらの条件が組み合わさると、攻撃者はJobs APIに到達し、攻撃者が制御するエントリーポイントを含むRayジョブを投入できます。Rayは投入されたワークロードを実行するよう設計されているため、これは最終的にRayプロセスの権限での任意コマンド実行につながる可能性があります。
脆弱なブラウザ判定ロジック
脆弱なロジックはray/python/ray/dashboard/optional_utils.pyに存在し、Rayのis_browser_request関数は、User-Agentヘッダーが「Mozilla」で始まるかどうかを確認することで、リクエストがブラウザ由来かどうかを判定しています。
つまり、このセキュリティ上の判断はクライアント側で制御可能なHTTPヘッダーに基づいて行われているのです。
# Conceptual reconstruction of the vulnerable guard
# NOT actual Ray source code
def is_browser_request(req):
ua = req.headers.get("User-Agent", "")
return ua.startswith("Mozilla")
def browsers_no_post_put_middleware(req, handler):
if req.method in ("POST", "PUT") and is_browser_request(req):
return Response("Browser requests not allowed", status=405)
return handler(req)
この保護策の背後にある前提は、ブラウザのJavaScriptがfetch()やXHRリクエストのUser-Agentヘッダーを変更できないというものでした。しかし、この点に関するブラウザの挙動は実装によって異なります。今回の攻撃シナリオでは、FirefoxとSafariはUser-Agentの上書きを許可する一方、Chromeはこの上書きを防止します。
そのため攻撃者は、Mozilla以外の値を使ったリクエストを送信できます。
fetch("http://target/api/jobs/", {
method: "POST",
headers: {
"User-Agent": "Other",
"Content-Type": "application/json"
},
body: JSON.stringify({
"entrypoint": "<test command>",
"runtime_env": {}
})
});
Rayは以下の内容のリクエストを受け取ります。User-Agent: Other
この値は「Mozilla」で始まっていないため、is_browser_request()はFalseを返します。その結果、リクエストはブラウザリクエスト用のミドルウェアをすり抜けて、Jobs APIへと処理が進みます。
重要なセキュリティ上の欠陥は、User-Agentがクライアントによって制御可能なリクエストメタデータであり、認証や認可の境界として使うべきではないという点です。
DNSリバインディングと組み合わさることで、このバイパスにより、攻撃者が用意したWebページが被害者のlocalhostで稼働するRay Dashboardに到達し、/api/jobs/経由でジョブを投入できてしまいます。Rayは投入されたワークロードを実行するよう設計されているため、ジョブ投入経路を制御されることは、最終的にRayプロセスが利用できる権限での任意コード実行につながる可能性があります。
脆弱性を示す概念的なアプリケーション
以下の例は、この脆弱なセキュリティパターンを再現した最小限のFlaskシミュレーションです。実際のRayのソースコードではなく、Rayの実装をそのまま再現したものと解釈すべきではありません。
このシミュレーションは、攻撃に関係する2つの条件を示しています。
- ジョブ投入用のエンドポイントが認証を必要としないこと。
- クライアントがヘッダーを制御できる場合にバイパス可能な、User-Agentチェックによってブラウザリクエストをブロックしていること。
# vulnerable_ray_app.py
# Conceptual lab simulation only — NOT actual Ray source code
from flask import Flask, request, jsonify
import subprocess
app = Flask(__name__)
def is_browser_request(req):
# Vulnerable assumption:
# browser requests always use a Mozilla-prefixed User-Agent.
ua = req.headers.get("User-Agent", "")
return ua.startswith("Mozilla")
@app.before_request
def guard_browser_post():
if request.method in ("POST", "PUT") and is_browser_request(request):
return "Browser requests not allowed", 405
@app.route("/api/jobs/", methods=["POST"])
def submit_job():
# Conceptual vulnerable pattern:
# an unauthenticated endpoint accepts an entrypoint
# and passes it to a shell executor.
body = request.get_json(force=True)
entrypoint = body.get("entrypoint", "")
subprocess.run(entrypoint, shell=True, check=False)
return jsonify({
"status": "submitted",
"entrypoint": entrypoint
})
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8265)
このシミュレーションが脆弱である理由
このブラウザ保護策は、User-Agentヘッダーのみに基づいてセキュリティ上の判断を下しています。return ua.startswith(“Mozilla”)
リクエストのUser-Agentが「Mozilla」で始まっている場合、ミドルウェアはそのリクエストを拒否します。値が異なる場合、リクエストはそのまま/api/jobs/へと進みます。
2つ目の問題は、/api/jobs/がジョブ定義を受け入れる前に認証を行っていないことです。この簡略化したシミュレーションでは、entrypointがそのままシェル実行関数に渡されてしまいます。
これは、このFlaskアプリケーションが実際のRayの実装そのものであると主張するものではなく、あくまで脆弱性の背後にあるセキュリティパターンを再現したものです。
この脆弱性が深刻である理由
- 認証不要:この攻撃は、脆弱なローカルサービスに対してRayの認証情報、APIトークン、VPNアクセスのいずれも必要としません。
- ブラウザ起点の侵入経路:被害者は、User-Agentバイパスの影響を受けるブラウザを使ってローカルでRayを稼働させている状態で、攻撃者が用意したWebページを閲覧するだけで済んでしまいます。
- DNSリバインディング:DNSリバインディングにより、攻撃者のWebページはlocalhostにバインドされたRay Dashboardに到達でき、さらに到達可能な内部の他のRayインスタンスにまで攻撃を拡大できる可能性があります。
- コード実行:ジョブ投入に成功すると、Rayのワークロード実行レイヤーに到達し、Rayプロセスの権限での任意コマンド実行につながります。
- 高い価値を持つ標的:Ray環境は、ソースコード、認証情報、データセット、モデルの成果物、クラウドリソース、そして相当量のCPU/GPU容量にアクセスできる場合があります。
- 横展開の可能性:侵害されたRayホストは、内部サービスや追加のRayインフラを発見・アクセスするための足がかりを攻撃者に与える可能性があります。
- 実際の悪用が確認済み:CISAは実際の悪用を理由にCVE-2025-62593をKEVカタログに追加しました。BitSightも、公開開示以前にRondoDoxがこの脆弱性の悪用を試みた活動を報告していますが、その際に観測された具体的な実装ではRayのブラウザ判定のバイパスには成功していませんでした
攻撃チェーン:悪意あるWebページから開発者ホストでのRCEまで
CVE-2025-62593は単一ステップで完結するエクスプロイトではありません。この攻撃は、ブラウザ、DNS解決、RayのDashboard、Jobs APIにまたがる複数の弱点を組み合わせたものです。攻撃者は悪意あるWebページを利用して被害者のマシン上で稼働するRayサービスに到達し、Dashboardのブラウザリクエスト保護をバイパスしてRayジョブを投入し、最終的にRayプロセスが利用できる権限でのコード実行を達成する可能性があります。
この攻撃は偵察、DNSリバインディング、User-Agentバイパス、ジョブ投入、リモートコード実行、侵害後の活動という6段階で構成されています。

1. 偵察
攻撃は、潜在的なRay環境を特定し、被害者のブラウザがこの攻撃経路に適しているかどうかを見極めることから始まります。
Rayは通常、DashboardをTCPポート8265で公開します。ローカル環境では、Dashboardは127.0.0.1:8265で利用できる場合があります。
攻撃者は、ローカルのRayサービスへの直接的なネットワークアクセスを必要としません。代わりに、被害者のブラウザがDashboardに到達できるかどうか、そしてその環境が脆弱な構成に一致するかどうかを見極めることが目的となります。
- 開発者やML技術者を標的にした不審なランディングページ。
- 見慣れないドメインが関与するブラウザ活動。
- 短いTTLのドメインが関わるDNSリクエスト。
- Ray Dashboardサービスへの予期しないアクセス。
2. DNSリバインディング
続いて攻撃者はDNSリバインディングを利用し、被害者のブラウザをローカルのRay Dashboardと通信させます。
当初、攻撃者が制御するドメインは攻撃者のインフラに解決されます。悪意あるページが読み込まれた後、そのドメインは127.0.0.1:8265のような、Rayに関連するローカルまたはプライベートアドレスに解決されるようになります。
そのため攻撃者は、被害者のループバックインターフェースに直接接続する必要はありません。被害者のブラウザが接続を行い、悪意あるWebページとローカルのRayサービスとの橋渡し役を果たします。
これが、Rayをlocalhostにバインドするだけではブラウザ起点の攻撃経路を必ずしも防げない理由です。
- 極端に短いDNS TTL。
- Aレコードの急速な変更。
- 外部アドレスとプライベート・ループバックアドレスの間を行き来するドメインの名前解決。
- ブラウザ活動の直後に続くローカルサービスへの接続。
3. User-Agentバイパス
ブラウザがRayに到達できるようになると、攻撃者はブラウザリクエストの保護をバイパスする必要があります。
脆弱なロジックは、ブラウザ発のリクエストを識別するためにUser-Agentヘッダーを使用しています。「Mozilla」で始まるUser-Agentを持つリクエストはブラウザリクエストとみなされ、機密性の高いPOST・PUT操作については拒否されます。
問題は、User-Agentがクライアント側で制御可能なメタデータであり、信頼できるセキュリティ境界ではないという点です。
実際に確認された攻撃経路では、FirefoxとSafariは該当のJavaScriptリクエストで異なるUser-Agent値を指定することを許可しています。そのため、「Other」のような値を使えば、脆弱な「Mozilla」チェックを回避できます。
概念的なリクエストは以下のとおりです。
fetch("http://target/api/jobs/", {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Other"
},
body: JSON.stringify({
"entrypoint": "<safe test command>",
"runtime_env": {}
})
});
ここでの重要なセキュリティ上の問題は、クライアントが制御できるヘッダーを認証や認可の境界として決して使うべきではないという点です。
- Rayエンドポイントに対する、通常とは異なるUser-Agent値を伴うPOST/PUTリクエスト。
- ブラウザ発でありながらブラウザらしくないUser-Agent文字列を使用しているリクエスト。
- Ray APIリクエストに関連する不審なOriginやReferer値。
4. ジョブ投入
ブラウザリクエストの保護をバイパスした後、攻撃者はRayのHTTPインターフェースに到達し、Jobs APIを標的にします。
該当するエンドポイントは以下です。/api/jobs/
Jobs APIは、Rayのワークロードを投入・管理するために設計されています。ジョブの投入にはentrypointが含まれ、ランタイム環境を指定することもできます。
代表的なリクエストは以下のとおりです。
POST /api/jobs/ HTTP/1.1
Host: 127.0.0.1:8265
Origin: https://attacker.example
User-Agent: Other
Content-Type: application/json
{
"entrypoint": "<attacker-controlled command>",
"runtime_env": {}
}
安全な検証用の実演例としては以下のようになります。
{
"entrypoint": "echo RAY_CVE_TEST",
"runtime_env": {}
}
この段階に至ると、攻撃はもはやブラウザリクエストの操作にとどまらなくなっています。攻撃者は、Ray実行環境にワークロードを投入できるインターフェースに到達しているのです。
- 予期しないPOST /api/jobs/リクエスト。
- 権限のない、あるいは通常とは異なるジョブの投入。
- 不審なentrypoint値。
- 不審なブラウザ活動の直後に発生するRayジョブ。
5. リモートコード実行
次の段階はリモートコード実行です。
Rayは投入されたワークロードを実行するよう設計されています。攻撃者がジョブ投入経路の制御を握った時点で、攻撃はHTTPリクエストの操作から、Rayランタイム内でのコード実行へと移行し得ます。
実行されるコンテキストはデプロイ形態によって異なります。開発者のワークステーションでは、Rayは開発者のアカウント権限で稼働している場合があります。クラスタ環境では、Rayワーカーや他の設定済み実行環境を通じて実行が行われることがあります。
したがって、悪用に成功すると、Rayプロセスが利用可能な以下のようなリソースへのアクセスが可能になる場合があります。
- ソースコード。
- 環境変数や設定情報。
- 認証情報やクラウドトークン。
- データベース。
- 学習用データセット。
- モデルの成果物。
- 内部サービス。
この時点が、CVE-2025-62593が単なるブラウザリクエストのバイパスではなく、RCEの脆弱性となる分岐点です。
- Rayワーカーが予期しないシェルやインタープリタを起動する。
- 不審な子プロセス。
- 見慣れないバイナリやスクリプト。
- 不審なアウトバウンド接続。
- Rayプロセスによる異常なファイルアクセス。
6. 侵害後の活動
Rayホスト上でのコード実行は、攻撃の始まりに過ぎない可能性があります。
環境を侵害した後、攻撃者は認証情報へのアクセスを試みたり、内部サービスを発見したり、さらに広範なインフラへと移動しようとしたりする場合があります。デプロイ形態や権限によっては、以下のような行動が含まれることがあります。
- クラウドの認証情報やAPIトークン。
- SSHキーやアプリケーションのシークレット。
- 内部APIやデータベース。
- 追加のRayクラスタ。
- 開発インフラ。
- クラウドリソース。
Ray環境は相当量のCPU・GPUリソースも提供しているため、暗号資産マイニングのような不正な演算に悪用される可能性があります。
攻撃者はさらに、永続化の確立や、侵害したRayホストを横展開の足がかりとして利用しようとする場合もあります。
- 認証情報へのアクセス活動。
- 内部ネットワークのスキャン。
- 他のRayクラスタへの予期しない接続。
- 暗号資産マイニングのトラフィック。
- 永続化の仕組み。
- 異常なCPU/GPU使用率。
代表的なHTTP通信の例
以下の通信は、DNSリバインディングによってブラウザがローカルで稼働するRay Dashboardへとリダイレクトされた後に生成されるリクエストを概念的に表現したものです。ホスト名は攻撃者が制御するものであり続けますが、接続は最終的に被害者のローカルのRayサービスに解決されます。
POST /api/jobs/ HTTP/1.1
Host: attacker.com
Origin: http://attacker.com
User-Agent: Other
Content-Type: application/json
{
"entrypoint": "<attacker-controlled command>",
"runtime_env": {}
}
投入が成功すると、以下のようなレスポンスが返る場合があります。
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "submitted",
"entrypoint": "<attacker-controlled command>"
}
安全な検証用の実演例では、entrypointには無害なコマンドを指定できます。
{
"entrypoint": "echo RAY_CVE_TEST",
"runtime_env": {}
}
このリクエストにおける重要な要素は以下のとおりです。
- POST /api/jobs/ — Rayのジョブ投入用インターフェースを標的にします。
- Host/ Origin — 攻撃者が制御するドメインに関連付けられたままです。
- User-Agent: Other — 脆弱な「Mozilla」プレフィックスチェックを回避します。
- entrypoint — 攻撃者が制御する、Rayへ投入されたワークロードを表します。
- runtime_env — 投入されたジョブに対する追加のランタイム設定を指定できます。
セキュリティ上重要なのは、このリクエストがブラウザに制御されたコンテキストから、Rayのワークロード実行インターフェースへと踏み込んでいる点です。ジョブが受理された場合、Rayは投入されたワークロードを通常の実行モデルに従って処理します。
公開ブログとしては、curl | bash、リバースシェル、暗号資産マイナーといったペイロードを含めることは避けるべきでしょう。無害なecho RAY_CVE_TESTの例だけで、この節をそのまま使える悪用ペイロードに変えることなく、脆弱なリクエストの流れを示すには十分です。
ラボ環境の構築と検証
以下のラボでは、この攻撃パターンの安全で自己完結したシミュレーションを提供します。実際のRayのソースコードではなく、Rayの実装をそのまま再現したものと見なすべきではありません。
このシミュレーションでは、いわゆる「confused deputy(混乱した代理人)」パターンを示しています。Flaskアプリケーションは「Mozillaのみ」を許可するブラウザガードと、認証なしのジョブエンドポイントを実装しており、別途用意されたHTMLページが改変したUser-Agentを使ってそのガードのバイパスを試みます。
実際の攻撃はDNSリバインディングに依存しています。ラボを持ち運び可能かつ再現性のあるものにするため、このシミュレーションでは外部のDNSインフラを再現する代わりにlocalhostを直接使用しています。
ラボの構成要素
- vulnerable_ray_app.py — 脆弱なブラウザリクエストチェックとジョブ投入エンドポイントを含む、概念的なRay Dashboardのシミュレーション。
- exploit.html — Mozilla以外のUser-Agentを用いてブラウザ発のリクエストを送信するデモ用Webページ。
- serve_exploit.py — デモ用ページをホストするために使う最小限のHTTPサーバー。
- run_lab_and_screenshot.py — ラボを起動し、ブラウザを立ち上げ、リクエストをトリガーして、結果をキャプチャするために使う任意の自動化スクリプト。
ラボでの検証結果
以下のスクリーンショットは、ラボの自動実行から取得したものです。dashboardのフィンガープリントチェック、悪意あるジョブを送信するexploitページ、偽装したUser-Agentを伴うPOSTを受理するサーバー、そして侵害の証拠となるマーカーファイルが作成される様子が示されています。
スクリーンショット1 — 概念的なRay dashboardのルートページ

スクリーンショット2 — リクエストをトリガーする前のexploitページ

スクリーンショット3 — HTTP 200と投入されたentrypointを示すexploitの実行結果

スクリーンショット4 — マーカーファイルの存在を確認する、侵害の証拠チェック

スクリーンショット5 — 偽装User-AgentによるPOSTが/api/jobs/に到達したことを示すサーバーログ

セキュリティへの影響
CVE-2025-62593は、悪意あるWebページへのアクセスを、Rayホスト上でのコード実行に変えてしまう可能性があります。実際の影響は、Rayプロセスの権限と、侵害された環境からアクセス可能なリソースに左右されます。
1. リモートコード実行
- Rayホスト上で任意のコマンドを実行する。
- Rayプロセスの権限でアクセスを取得する。
- 悪意あるツールやスクリプトをインストールする。
2. データと認証情報の窃取
- ソースコードや設定ファイル。
- クラウドの認証情報やAPIキー。
- SSHキーやアプリケーションのシークレット。
- 学習データやモデルの成果物。
3. リソースの不正利用
- 暗号資産マイニング。
- 不正なCPU/GPUワークロード。
- リソースの枯渇。
- クラウドインフラのコスト増加。
4. 横展開(ラテラルムーブメント)
- 内部サービスやデータベースを発見する。
- クラウドやプライベートインフラにアクセスする。
- 追加のRayクラスタに到達する。
- 侵害したホストを内部での足がかりとして利用する。
5. 機械学習資産の露出
- モデルの重みやチェックポイントを窃取する。
- 学習用データセットにアクセスする。
- 機械学習ワークロードや成果物を改ざんする。
- 独自の研究内容を露出させる。
6. 永続化とサプライチェーンリスク
- 依存関係やランタイム環境を改変する。
- 悪意あるワークロードやパッケージを持ち込む。
- 侵害した環境へのアクセスを維持する。
- 接続されている他のワークロードに影響を及ぼす可能性がある。
7. 開発者ワークステーションの侵害
- 開発用リポジトリにアクセスする。
- ローカルの環境変数や設定ファイルを読み取る。
- 開発者が利用可能な認証情報を悪用する。
- より広範な開発環境へとピボットする。
全体的な影響
ブラウザ経由のアクセス、脆弱なブラウザリクエスト検証、そしてRayのワークロード実行機能が組み合わさることで、悪意あるWebページが開発者のワークステーションやRayクラスタへの足がかりに変わり得ます。そこから攻撃者は、認証情報や機械学習資産を窃取したり、計算リソースを不正利用したり、接続されたインフラのより深いところへと侵入したりする可能性があります。
修正と緩和策
CVE-2025-62593に対する主な対策は、Rayをバージョン2.52.0以降にアップグレードすることです。Ray 2.52.0では、この脆弱性に関連するブラウザリクエストの保護強化が導入され、Ray 2.52.1ではより広範なブラウザヘッダーの検証が追加されているため、多層防御の観点からはこちらのバージョンが望ましいといえます。
Ray 2.52.0では、Dashboard、CLI、APIクライアント、内部サービス向けのトークン認証も導入されました。認証はデフォルトでは有効になっていないため、管理者はブラウザリクエストの保護策のみに頼るのではなく、明示的にこれを有効化すべきです。
即座に取るべき対応
- 直ちにRayをアップグレードする
- すべてのRayインストールを2.52.0以降にアップグレードする。
- 可能であれば2.52.1を優先する。
- 開発者のワークステーション、CI/CD環境、研究用システム、Kubernetesデプロイ、本番クラスタをすべて棚卸しの対象に含める。
- Rayのトークン認証を有効化する
- Ray DashboardとAPIインターフェースの認証を有効化する。
- CLIクライアントや内部サービスにも同様の認証要件を適用する。
- User-Agentやその他のクライアント制御下のヘッダーをアクセス制御の仕組みとして頼らない。
- Rayのネットワーク露出を制限する
- ポート8265がインターネットに直接公開されていないことを確認する。
- ファイアウォール、セキュリティグループ、ネットワークACL、VPN制御を用いてRay管理インターフェースへのアクセスを制限する。
- Rayサービスをすべてのネットワークインターフェースに不必要に公開するのではなく、明示的なインターフェースにバインドする。
- 露出した可能性のある認証情報を確認する
- 脆弱なRayホストからアクセス可能な認証情報を特定する。
- 露出の可能性を否定できないクラウドの認証情報、APIキー、データベースのパスワード、SSHキー、その他の機密情報をローテーションする。
- 影響を受けたシステムに関連する認証情報の不審な使用がないか、クラウドの監査ログを確認する。
- 悪用の痕跡を調査する
- 過去のRay DashboardおよびJobs APIの活動履歴を確認する。
- /api/jobs/への予期しないリクエストを探す。
- RayへのPOST/PUTリクエストに関連する不審なUser-Agent値を調査する。
- 短いTTLや急速に変化する不審なドメインがないか、DNSテレメトリを確認する。
- Rayプロセスから起動されたシェル、インタープリタ、見慣れないバイナリがないか、EDRのテレメトリを確認する。
- 実行中のワークロードを点検する
- 実行中および直近で完了したRayジョブを確認する。
- 予期しないジョブの投入、見慣れないentrypoint、権限のないランタイム環境がないか確認する。
- 説明のつかないCPU/GPU消費や不審なアウトバウンド接続がないか調査する。
結論
CVE-2025-62593は、一見些細に見える複数のセキュリティ上の弱点が組み合わさることで、いかに重大な攻撃経路になり得るかを示しています。DNSリバインディング、脆弱なUser-Agentベースのブラウザ保護、認証なしのジョブ投入を組み合わせることで、攻撃者が用意したWebページはローカルのRayサービスに到達し、任意コード実行を達成し得ます。
その影響はRayプロセス自体をはるかに超えて広がる可能性があります。侵害された開発者のワークステーションやRayノードは、ソースコード、認証情報、学習データ、モデルの成果物、クラウドリソース、内部サービスを露出させるおそれがあり、利用可能なCPU・GPUリソースも不正利用される可能性があります。
Rayを運用している組織は、この脆弱性を優先度の高いセキュリティ問題として扱うべきです。Ray 2.52.0以降、できれば2.52.1へのアップグレード、トークン認証の有効化、Ray管理インターフェースへのアクセス制限、そして脆弱なシステムにおける侵害の兆候の調査を行う必要があります。
より広い教訓は明確です。localhostは自動的に信頼できるセキュリティ境界にはならないということです。ワークロードを実行できる管理インターフェースは、ブラウザの挙動やクライアント制御下のヘッダーに頼るのではなく、強固な認証とネットワーク制御によって保護されるべきです。