本文へ移動
English version →
重大 9.9 急ぎ度: 至急

Beta9 workerにコンテナ脱出の脆弱性、修正版あり

Beta9のworkerに、サンドボックスの利用者がホスト側のファイルを読み書きできる脆弱性が見つかりました。複数の利用者にBeta9を使わせている組織は、worker 0.1.756へ更新し、サービスアカウントの権限も見直してください。

CVE-2026-120307 公開 更新 執筆・監修: 佐々木 航 人が監修しながらAIを活用して執筆
画像は生成 AI で作成したイメージです

急ぎ度: 至急

CVSS v3は9.9で、低い権限からworkerのホストをrootで操作でき、同梱のマニフェストではcluster-admin相当のトークンまで読める一方、修正版0.1.756はすでに公開されています。

関係があるか

Beta9を自社運用し、社内の別チームや社外の利用者にサンドボックスを使わせている組織が対象です。利用者が自分のワークスペースのトークンで操作できる環境なら、利用者が1人でも当てはまります。

製品影響を受ける版修正版
Beta9 worker(beam-cloud) 0.1.756より前 0.1.756

確かめ方

  1. 1Beta9のworkerを動かしているクラスターや仮想マシンで、workerのイメージタグや実行ファイルの版を確認し、0.1.756より前かどうかを見ます。
  2. 2同梱のremote-nodeのマニフェストでworkerをデプロイした場合は、そのサービスアカウントがcluster-adminに結び付いていないかも、あわせて確認します。
  3. 3利用者に発行しているワークスペーストークンの数と、サンドボックスを使える人の範囲を洗い出し、信頼できない利用者がいないかを見ます。
  4. 4クラウドで提供されるBeta9の利用者は、ベンダーの告知で自分の環境が修正済みかどうかを確認してください。

何が起きたか

Beta9のworkerにあるサンドボックス用のファイルAPIで、利用者が指定したパスの検査に抜け道があります。悪用されると、サンドボックスの外にいるworkerのホスト上のファイルを、利用者が読み書き・一覧・削除できてしまいます。

このファイルAPIは、コンテナの外側にいるworkerが処理します。workerは、利用者が渡したコンテナ内のパスを、worker側のパスに変換します。ところが、マウント先と一致するかの検査が済んだあとに、パスの中の親ディレクトリを指す部分が整理されるため、検査を通った名前がマウントの外を指せてしまいます。どのマウントにも当てはまらないパスは、workerが自分のファイルシステムで開き、絶対パスのシンボリックリンクもworker側のルートを基準にたどります。

アップロード、ダウンロード、stat、一覧、ファイル内検索、ファイル内置換、ファイル削除の各操作が、この変換処理を通ります。修正版のworker 0.1.756では、サンドボックスのファイル操作とワークスペースの同期がos.OpenRootでパスを開くようになりました。親ディレクトリやシンボリックリンクをたどっても、コンテナのルートかマウント元の内側にとどまります。

攻撃の流れ

  1. 1

    利用者として入る

    ワークスペーストークンと、実行中のサンドボックスを1つ持つ利用者が、ファイルAPIを呼びます。

  2. 2

    パス検査をすり抜け

    検査のあとにパスが整理されるため、マウントの外を指す名前が通ります。

  3. 3

    ホストのファイル操作

    worker上のファイルを、root権限で読み書き・一覧・削除できます。

  4. 4

    認証情報の入手

    ほかの利用者のファイルや、workerのサービスアカウントトークンが読み出されます。

  5. 5

    クラスターへ波及

    同梱のマニフェストでは、そのトークンがcluster-adminに結び付いています。

公開されている情報をもとにした流れの例です。

どう悪用されるか

ネットワーク越しに攻撃でき、複雑な条件は要りません。必要なのは、ワークスペーストークンと、実行中のサンドボックス1つだけです。管理者権限は要らず、ほかの人にリンクを踏ませるような操作も要りません。

成功すると、worker上のファイルをrootとして読み書き・一覧・削除できます。同じマシン上にあるほかの利用者のファイルも対象です。研究者は読み取りだけの検証で、サンドボックス内に存在しないパスを指定し、workerのPodのKubernetesサービスアカウントトークンをファイルAPIでダウンロードできることを示しました。

同梱のremote-node用マニフェストでは、このサービスアカウントがcluster-adminに結び付いています。トークンが読み出されれば、被害はworker1台にとどまらず、クラスター全体に及ぶおそれがあります。

今すぐやること

  1. 1

    workerを0.1.756に更新する

    すべてのworkerを修正版へ更新します。更新後は、古い版のworkerがノードに残っていないか確認してください。

    kubectl get pods -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,IMAGE:.spec.containers[*].image
  2. 2

    トークンが漏れた前提で点検する

    信頼できない利用者がいた環境では、workerのサービスアカウントトークンが読まれた可能性があります。更新後にトークンを再発行し、Kubernetesの監査ログで、そのサービスアカウントからの想定外の操作がないかを調べます。

  3. 3

    サービスアカウントの権限を絞る

    同梱のマニフェストのままcluster-adminを付けている場合は、workerに必要な範囲の権限へ絞れないかを検討します。動作に影響するため、検証環境で確認してから変更してください。

  4. 4

    ワークスペーストークンを棚卸しする

    使われていないトークンや、退職・異動した人のトークンを失効させます。サンドボックスを使える人の範囲も見直します。

  5. 5

    ベンダーの告知を確認する

    beam-cloudのリリースノートと修正の説明を読み、自分の環境の構成で追加の作業が要らないかを確認します。

すぐ更新できないとき

修正版を当てるまでのつなぎとして、信頼できない利用者のサンドボックス利用を止める、またはワークスペーストークンを一時的に失効させる方法があります。あわせて、workerのサービスアカウントの権限を絞ると、トークンが読まれたときの被害を小さくできます。ただし、これらはパスの検査の不備そのものを直すわけではありません。公式の回避策の有無は、ベンダーの告知で確認してください。

背景

Beta9は、beam-cloudが公開しているオープンソースの基盤で、AIの推論やジョブを、利用者ごとに分けたコンテナ(サンドボックス)で動かします。workerは、そのコンテナを実際に動かすノード側のプログラムです。ファイルのアップロードやダウンロードも、コンテナの中ではなく、外側のworkerが代わりに処理します。

コンテナの外で、コンテナ内のパスを解釈する処理は、Dockerのdocker cpやKubernetesのkubectl cpでも脆弱性の原因になってきました。親ディレクトリを指す表記やシンボリックリンクが、コンテナの外のパスとして解決されてしまうためです。今回も同じ型で、マルチテナントの基盤では利用者のあいだの壁が崩れます。さらに、workerの権限が広いと、1台の侵害がクラスター全体に広がります。

よくある質問

Q.利用者が自社の社員だけでも、更新は急ぐべきですか。
A.急いでください。社員でもワークスペーストークンが漏れれば、同じ操作ができてしまいます。社外の利用者がいる環境ほど危険は高いですが、社内だけの運用でも、トークンの流出がcluster-admin相当の権限につながるおそれがあります。
Q.更新したあとに、侵害の跡を確かめる手がかりはありますか。
A.Kubernetesの監査ログで、workerのサービスアカウントが普段と違うAPIを呼んでいないか、見慣れない場所から使われていないかを調べます。ワークスペーストークンごとのファイルAPIの呼び出し履歴が残っていれば、存在しないパスへのアクセスも手がかりになります。

この記事は、取得元の公開情報をもとに、人が監修しながらAIを活用して執筆しています。執筆と監修は佐々木 航が担い、公開したあとも人が内容を確認しています。誤りに気づいたときは直し、記事の末尾に訂正の行を残します。対応を決める前に、下の原文と参照先も確認してください。

影響パッケージ

種類パッケージ影響を受ける版修正版
beam-cloud Beta9 worker
0.1.756 未満
0.1.756
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。

The Beta9 worker serves the sandbox file API from outside the container. getHostPathFromContainerPath turns the tenant's container path into a worker path. If the unresolved path starts with a mount destination, including the default upload mount at /tmp/.beta9, the remainder is joined onto that mount's source with filepath.Join, which cleans parent-directory segments after the prefix check. A long enough run of those segments names any absolute path on the worker. A path that matches no mount is joined onto the container root and opened in the worker's own filesystem, so an absolute symbolic link such as /var/run pointing at /run is followed against the worker root. Upload, download, stat, list, find-in-files, replace-in-files, and delete-file all call this helper. A tenant with a workspace token and one running sandbox can read, write, list, and delete files on the hosting worker as root, including files of other tenants on that machine. A read-only proof downloaded the worker pod's Kubernetes service account token through the file API for a path that did not exist inside the sandbox. In the shipped remote-node manifests that service account is bound to cluster-admin. Fixed in worker 0.1.756: sandbox file operations and workspace sync open paths with os.OpenRoot, so parent-directory and symlink lookups stay inside the container root or the mount source.

出典: CVE.org (CVE Program・cvelistV5) NVD GitHub Advisory

参照URL

当サイトでは、アクセス解析と広告の効果測定のために Cookie を使います。株式会社Game のサイト共通の設定です。 詳しく