Mercury、認証なしでOSシェルを奪われる欠陥 3.2.4で修正
ノートブックをWebアプリとして公開するOSS「Mercury」に、ログインなしでサーバー上のシェル(OSへの命令入力画面)を起動できる欠陥が見つかりました。Mercury 3.0.0 以上 3.2.4 未満を動かしている組織が対象で、インターネットや社内の広い範囲に公開している場合は特に危険です。修正版 3.2.4 へ更新し、更新までは /api/terminals への通信を前段で遮断してください。
急ぎ度: 至急
認証も利用者の操作も要らず、ネットワークから到達できるだけでサーバーを完全に操作されるため(CVSS 10.0)、公開範囲が広い環境では更新を待たずに遮断が必要です。
関係があるか
Mercury 3.0.0 以上 3.2.4 未満をサーバーやコンテナで動かし、そこへネットワークから届く環境が対象です。VPN、リバースプロキシの認証、ファイアウォールなどで守っていない公開インスタンスは、最も危険です。
| 製品 | 影響を受ける版 | 直った版 |
|---|---|---|
| Mercury(PyPI パッケージ `mercury`) | 3.0.0 以上 3.2.4 未満(公表内容によっては「3.2.4 未満」とだけ記載されています) | 3.2.4 |
確かめ方
- 1Mercury を動かしているサーバーやコンテナで
pip show mercuryを実行し、Version が 3.2.4 未満でないかを確認します。 - 2Docker で配備している場合は、イメージを作った時点の版が使われ続けます。起動中のコンテナ内で上の確認をするか、Dockerfile やイメージの版指定を見直してください。
- 3Mercury の待ち受けポート(例: 8888)に、インターネットや他部署のネットワークから届くかを、ファイアウォール、ロードバランサー、リバースプロキシの設定で確認します。
- 4Mercury を導入した担当者が分からない場合は、社内の Python 環境や ML・データ分析用の基盤で
pip listを実行し、mercuryが入っていないか棚卸しします。
何が起きたか
Mercury は、公開してはいけない管理用の機能へのアクセスを、URL のパターン一覧(ブロックリスト)で止める作り方をしています。この一覧の書き方に不備があり、ターミナル機能の入口である /api/terminals が止められていませんでした。その結果、ログインしていない人でも、Mercury が動くサーバー上でコマンドを入力できる画面を開けてしまいます。
原因は、mercury_app/block_handler.py の BLOCKED_PATTERNS というリストで、1 行目と 2 行目の間のカンマが抜けていたことです。Python では、カンマなしで並んだ文字列が 1 つにつながります。そのため、2 つのパターンが「1 つの別のパターン」に変わり、/api/terminals 単独の遮断ルールが無くなりました。遮断されなかった要求は、Jupyter Server に組み込まれたターミナル API に届き、WebSocket 経由で本物の OS シェルが使えるようになります。
報告者は、公式の Docker 構成(Mercury 3.2.3、既定の設定)で再現を確認しています。その環境ではシェルが root 権限で動いていました。修正版の 3.2.4 では、このカンマが補われ、/api/terminals が独立したルールとして遮断されます。
攻撃の流れ
-
1
到達する
攻撃者が、Mercury のサーバーへネットワーク経由で接続できる位置にいます。
-
2
遮断の抜け
ターミナル用の入口が、ブロックリストで止められていません。
-
3
シェル起動
ログインなしで、サーバー上にコマンド入力画面が作られます。
-
4
サーバー掌握
ファイルの閲覧・改ざん・削除、環境変数の窃取、サーバーの停止が可能になります。
-
5
内部へ拡大
そのサーバーを足がかりに、同じネットワークの他のシステムが狙われます。
どう悪用されるか
悪用に必要なのは、Mercury のサーバーにネットワークから接続できることだけです。アカウント、セッション、事前のアクセス権、利用者のクリックなどは要りません。攻撃の難しさは低く、CVSS のベクトルでも、認証不要(PR:N)、利用者の操作不要(UI:N)、ネットワーク経由(AV:N)と評価されています。VPN、リバースプロキシでの認証、ファイアウォールなどの追加の防御が無い公開環境では、インターネット上の誰からでも到達できます。
悪用された場合、Mercury のプロセスが読めるファイルはすべて読み取られます。ノートブック、アップロードされたデータ、環境変数に置いた API キーやパスワードなどの秘密情報が含まれます。ファイルの改ざん・削除や、他の利用者に配信しているノートブックの書き換えも可能です。サーバーやコンテナの停止もできます。さらに、サーバーから届く社内の他システムへの侵入の足がかりにもなります。
実際の攻撃で悪用されたという公表は、現時点では確認できていません。ただし、攻撃の前提が低く、仕組みも公開されているため、公開状態のインスタンスは早急な対応が必要です。
今すぐやること
-
1
使っている版を確認する
Mercury を動かしている環境で版を確認し、3.2.4 未満なら対象です。Docker の場合は、起動中のコンテナ内で確認してください。
pip show mercury -
2
公開範囲を絞る、または一時停止する
インターネットから直接届く状態なら、更新前でもまずファイアウォールやセキュリティグループで接続元を絞ります。絞れない場合は、更新が終わるまでサービスを止める判断も検討してください。
-
3
Mercury 3.2.4 以上へ更新する
パッケージを 3.2.4 以上に更新し、サービスを再起動します。Docker の場合はイメージを作り直して入れ替えます。更新後に、もう一度版を確認してください。
-
4
侵入の形跡を調べる
更新前に公開状態だった期間のアクセスログ(リバースプロキシやロードバランサーを含む)で、
/api/terminalsや/terminals/への要求が無いかを確認します。見慣れない送信元、想定外のプロセス、ファイルの変更、不審な外向きの通信が無いかも見てください。 -
5
秘密情報の入れ替えを検討する
形跡があった場合、または公開状態で長く動かしていて判断できない場合は、Mercury の環境に置いていた API キー、パスワード、トークンを新しいものに替えます。
-
6
社内の導入状況を棚卸しする
検証用や個人のサーバーに、Mercury が残っていないかを確認します。見つかったものも同じ手順で更新するか、不要なら停止してください。
すぐ更新できないとき
すぐに更新できない場合は、Mercury の手前(リバースプロキシ、WAF、ロードバランサー、ファイアウォール)で、/api/terminals とその配下、およびターミナル用の WebSocket の入口への要求を遮断してください。あわせて、Mercury へ接続できる送信元を VPN や社内ネットワークに限り、前段で認証をかけると、被害の可能性を下げられます。ただし、これらは更新までの一時的な対策です。Mercury 自体の修正は 3.2.4 への更新で行います。
背景
Mercury は、Jupyter ノートブックを Web アプリやダッシュボードとして共有できるオープンソースのツールです。分析担当者が作った成果物を、社内の他の人に見せる用途で使われます。そのため、データ基盤や社内ネットワークの近くで動くことが多く、サーバーを乗っ取られたときの影響が大きくなりがちです。
Jupyter 系のサーバーは、ターミナル機能を使うと OS のシェルが動く設計で、認証なしで公開すると深刻な問題になります。Mercury は、この機能を利用者に見せないために、URL のブロックリストで止める方式を取っていました。禁止する項目を並べる方式は、書き方の小さな誤りでも、そのまま抜けになります。今回はカンマ 1 つの抜けが、全体の安全性を壊しました。この種の問題を防ぐには、公開するものだけを許可する方式や、前段での認証を併用する設計が有効です。
よくある質問
Q.社内だけで使っていれば影響はありませんか。
Q.Mercury に認証を設定していれば安全ですか。
Q.実際に攻撃は起きていますか。
Q.更新後に何を確認すればよいですか。
pip show mercury で版が 3.2.4 以上になっていることと、サービスが正常に起動していることを確認します。あわせて、更新前の公開期間に不審なアクセスが無かったかをログで確認してください。まだ分かっていないこと
- 実際の攻撃で悪用されたかどうかは、公表されていません。
- 3.0.0 より前の版が影響を受けるかは、公表内容によって記載が異なります。使っている版が古い場合は、ベンダーの告知で確認してください。
この記事は、取得元の公開情報をもとに生成 AI で作成しています。誤りを含むことがあります。対応を決める前に、下の原文と参照先を確認してください。
影響パッケージ
| 種類 | パッケージ | 影響を受ける版 | 直った版 |
|---|---|---|---|
| pip | mercury |
3.2.4 未満 |
3.2.4 |
| PyPI | mercury |
3.0.0 以上 3.2.4 未満 |
3.2.4 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
Mercury is a Python framework for sharing Jupyter notebooks as web applications and dashboards. From 3.0.0 until 3.2.4, a missing comma in BLOCKED_PATTERNS concatenates the /lab and /api/terminals regular-expression literals. Requests to /api/terminals therefore bypass the anonymous endpoint blocklist and reach Jupyter Server's terminal API. An unauthenticated attacker can use the resulting interactive operating-system shell to execute commands and access data available to the Mercury process. This issue is fixed in version 3.2.4.
出典: GitHub Security Advisories (Global) NVD GitHub Advisory
参照URL
- advisory github.com
- advisory github.com
- advisory nvd.nist.gov
- package github.com
- patch github.com
- web github.com
- web github.com