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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-34048 — 管理者専用のターミナルブートストラップルートはログイン状態のみをチェックするため、通常のチームメンバーがCoolifyのリアルタイムターミナルバックエンドを操作し、チームサーバー上でコマンドを実行できるようにします。 | Kitploit
ツール/GitHubGitHub/0xmrma/cve-2026-34048
認証と認可特権昇格脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテストクラウドセキュリティコマンド&コントロールレッドチーミング
GitHub0xmrma/cve-2026-34048

CVE-2026-34048

管理者専用のターミナルブートストラップルートはログイン状態のみをチェックするため、通常のチームメンバーがCoolifyのリアルタイムターミナルバックエンドを操作し、チームサーバー上でコマンドを実行できるようにします。

1ヶ月前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有
リポジトリを見る

CVE-2026-34048

管理者専用のターミナルブートストラップルートがログイン状態のみをチェックしていたため、通常のチームメンバーがCoolifyのリアルタイムターミナルバックエンドを操作し、チームサーバー上でコマンドを実行できるようになっていました。

はじめに

この問題は、オープンソースのセルフホスト型PaaSであるCoolifyをレビュー中に発見しました。その際、非常に直接的なセキュリティ上の問いを念頭に置いていました。

ターミナルアクセスは、実際にバックエンドの信頼境界で強制されているのか、それともUIだけで行われているのか?

今回のケースでは、答えは悪いものでした。

Coolifyはターミナルアクセスをチーム管理者と所有者に制限することを意図していましたが、リアルタイムターミナルのブートストラップルートは、ユーザーがログインしているかどうかのみをチェックしていました。これにより、低権限のチームメンバーがWebSocketターミナルの信頼チェックを満たし、チームサーバー上でのコマンド実行に至ることができました。

私はこの問題を、脆弱性のあるリビジョンから構築したローカルラボでエンドツーエンドで検証し、その後非公開で報告しました。この問題にはCVE-2026-34048が割り当てられ、次のCVSSスコアが付与されました。

root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

Coolify: Coolify on GitHub
CVE: CVE-2026-34048

これはオープンソースのセルフホスト型PaaSであるCoolifyに影響します。公式サイトでは、Coolifyは3,641以上のクラウド顧客がいると述べ、Webサイト、データベース、Webアプリケーション、280以上のワンクリックサービスをデプロイするためのプラットフォームとして紹介されています。また、公式v4.0の変更履歴には、数千の企業と個人が1〜2年間、Coolifyを本番環境で使用していると記載されています。

photo0


攻撃チェーン

低権限チームメンバーのセッション -> /terminal/auth および /terminal/auth/ips はログイン状態のみをチェック -> リアルタイムWebSocketがそれらの応答を信頼 -> メンバーがチームサーバーと可視のSSHキーUUIDを列挙 -> /terminal/ws がセッションを受け入れる -> SSHバックアップPTYが生成される -> チームサーバー上でシェルアクセス


Coolifyの機能

Coolifyは、セルフホスト型のPaaSおよびデプロイプラットフォームです。

以下のものを管理します:

  • サーバー
  • アプリケーション
  • デプロイ
  • 秘密鍵
  • チーム権限
  • 管理対象インフラストラクチャへのターミナルアクセス

最後の機能がここで重要です。

プラットフォームが管理ホストへのターミナルを開くことができるようになると、その認可モデルは単なるアプリケーションロジックではなくなります。 それはインフラストラクチャの信頼境界になります。

重要な質問は、/terminalページが管理者専用に見えるかどうかではありませんでした。

本当の質問は次の通りです。

バックエンドのターミナルパスは、WebSocketセッションが作成される際に、実際に同じ認可境界を強制しているか?

このケースでは、強制されていませんでした。


このバグが見る価値があった理由

ターミナル機能は、インフラストラクチャソフトウェアの中でも最も価値の高い表面の一部です。

なぜか?

なぜなら、以下の間のいずれかの不一致が:

  • UIの認可
  • バックエンドの認可
  • WebSocketのブートストラップロジック
  • ホストのコマンド実行

通常のアプリケーションユーザーをシェルを使用可能なオペレーターに変える可能性があるからです。

まさにそのため、この表面をテストする価値がありました。

私はランダムなクラッシュや表面的な権限バグを探していたわけではありません。

私はより強力な障害クラスを探していました。

管理者専用の機能が、UIが示唆するよりも弱いバックエンドの信頼チェックに依存していないか?

それが正しい質問でした。


私が焦点を当てた境界

私はCoolifyにアプローチする際、ランダムなエンドポイントをファジングして何か面白いことを期待したわけではありません。

より強力なアプローチは、最初に最もリスクの高い境界を特定することでした。

Coolifyの場合、その境界はターミナルワークフローでした。

  • UIはターミナルアクセスが制限されていると示す
  • ターミナルサービスはWebSocketベース
  • WebSocketサービスは通常、別個のブートストラップ信頼ロジックを持つ
  • ターミナルコマンドは最終的にアプリケーション状態からホスト実行へと渡る

これにより、ブートストラップルートが適切な調査場所となりました。

そして、そこに問題がありました。


根本原因

根本原因は、ターミナルUIとターミナルWebSocketブートストラップルートの間の認可の不一致でした。

脆弱性のあるリビジョンでは:

  • GET /terminal は can.access.terminal によって保護されていた
  • POST /terminal/auth は auth()->check() のみチェックしていた
  • POST /terminal/auth/ips は auth()->check() のみチェックしていた

つまり、UIはターミナル認可によってゲートされていたが、バックエンドの信頼境界は単純な認証済みセッションの存在によってゲートされていたのです。

そして、リアルタイムサービスはこれら2つのルートを完全に信頼していました。

docker/coolify-realtime/terminal-server.js において:

  • verifyClient() は POST /terminal/auth にPOSTしていた
  • WebSocketセッションのセットアップは POST /terminal/auth/ips にPOSTしていた
  • WebSocketハンドラは、攻撃者が提供したターミナルコマンド入力を受け入れ、ターゲットホストが返されたホストリストに含まれているかどうかのみをチェックしていた

それがバグチェーン全体です。

なぜこれが悪用可能か

通常のチームメンバーは、通常のアプリケーション表面から必要な入力を構築できたからです。

  • /servers は可視のサーバーUUIDを公開していた
  • /server/{uuid} は ip、user、port をレンダリングされたフォームフィールドとして公開していた
  • /security/private-key は可視のチーム秘密鍵UUIDを公開していた
  • ターミナルパスは、次の形式の決定論的なパスを通じてキーを参照していた:
root@kitploit:~
/var/www/html/storage/app/ssh/keys/ssh_key@<uuid>

したがって、悪用パスは単純でした:

  • 管理者以外のチームメンバーとしてログイン
  • /terminal/auth を呼び出す
  • /terminal/auth/ips を呼び出す
  • 可視のサーバーを列挙する
  • 可視のキーUUIDを列挙する
  • /terminal/ws に接続する
  • バックエンドが期待するのと同じSSHコマンド形状を送信する
  • チームホストからのシェル出力を受け取る

これは理論上の不一致ではありません。 これは実際のバックエンド認可の失敗です。


これが単なるUIの不一致ではなく、セキュリティ問題である理由

重要な区別は、バックエンドの信頼とコマンド実行です。

多くのバグは次のように見えます:

  • 「ボタンが隠れている」
  • 「ページがブロックされている」
  • 「UIがここにいるべきでないと表示する」

それだけでは不十分です。

本当の質問は次の通りです。

低権限のユーザーは、重要なバックエンドの信頼チェックを依然として満たせるか?

このケースでは、答えは「はい」でした。

これは次のようなものではありませんでした:

  • 壊れたメニュー
  • フロントエンドチェックの欠落
  • 表面的なルーティング問題

それは次のようなものでした:

  • WebSocketブートストラップの認可が弱すぎる
  • ターミナルホストの認可がその弱い信頼境界から導出されている
  • 管理対象インフラストラクチャ上での実際のシェルアクセス

だからこそ、これは本当のセキュリティ問題だったのです。


PoC

私はこれを、次のリビジョンから構築した制御されたローカルラボで検証しました。

root@kitploit:~
06f60c9a98bead0c932c6adf7fd43a45d9149048

ラボでは以下を使用しました:

  • ベースURL: http://127.0.0.1:18000
  • 低権限メンバーアカウント: [email protected]
  • ターゲットサーバー: localhost -> coolify-testing-host:22 as root
  • 可視キーUUID: ssh
  • WebSocketエンドポイント: ws://127.0.0.1:6002/terminal/ws

ステップ1: UIの境界を確認する

メンバーアカウントは、通常の管理者向けUIを通じてターミナルアクセスを持つことを意図されていませんでした。

これにより、期待されるセキュリティ境界が確立されました。

ステップ2: ブートストラップルートを直接呼び出す

メンバーセッションを使用して、次のリクエストを送信しました:

  • POST /terminal/auth
  • POST /terminal/auth/ips

両方とも成功しました。

/terminal/auth/ips は、次のターミナル認可ホストを返しました:

root@kitploit:~
coolify-testing-host
host.docker.internal
localhost
127.0.0.1

これにより、バックエンドのブートストラップルートがメンバーセッションを信頼していることが証明されました。

ステップ3: サーバーとキーのメタデータを列挙する

通常の認証済みページから、同じメンバーが以下を列挙できました:

  • 可視のサーバーUUID
  • サーバー接続フィールド
  • 可視のチーム秘密鍵UUID

これで、秘密鍵マテリアルの開示を必要とせずにターミナルパスを駆動するのに十分な情報が得られました。

ステップ4: ターミナルWebSocketを開く

同じ認証済みセッションとXSRFトークンを使用して、次のエンドポイントに接続しました:

root@kitploit:~
ws://127.0.0.1:6002/terminal/ws

ステップ5: ターミナルコマンドペイロードを送信する

ペイロードは、ターミナルバックエンドが期待するのと同じコマンド形式を使用しました:

root@kitploit:~
{"command":["timeout 30 ssh -i /var/www/html/storage/app/ssh/keys/ssh_key@ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o ConnectTimeout=10 -o ServerAliveInterval=5 -o RequestTTY=no -o LogLevel=ERROR -p '22' 'root'@'coolify-testing-host' 'bash -se' << \\P0C\nprintf '__COOLIFY_POC_BEGIN__\\n'; id; whoami; hostname; printf '__COOLIFY_POC_END__\\n'\nP0C"]}

ステップ6: リモートシェル出力を観察する

WebSocketは次のものを返しました:

root@kitploit:~
pty-ready
__COOLIFY_POC_BEGIN__
uid=0(root) gid=0(root) groups=0(root)
root
efa027413801
__COOLIFY_POC_END__

それが重要な証明でした。

単に:

  • ルートアクセス
  • WebSocketの受け入れ
  • メタデータの露出

ではなく、管理者専用のターミナルパスを通じて管理ホスト上で実際にコマンドが実行されたことです。


このPoCが強力だった理由

このチェーンの一部だけでも、すでに興味深いものでした。

例えば:

  • メンバーによる /terminal/auth へのアクセス
  • またはメンバーによる /terminal/auth/ips へのアクセス

しかし、それだけでは却下の余地が残ります。

より強力な検証はエンドツーエンドでした:

  • メンバーセッション
  • バックエンドブートストラップの成功
  • WebSocketの受け入れ
  • PTYの作成
  • リモートシェル出力

これにより、「理論上の認可バグ」と「現実のインフラストラクチャへの影響」の間のギャップが埋まりました。

また、深刻度の弁護がはるかに容易になりました。


深刻度と分類

この問題はCriticalとして適切に分類されました。

分類は次のとおりです:

  • CWE-862: 認可の欠如
  • CVSS:
root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

それは理にかなっています。

主張は、未認証の攻撃者が何もないところからシェルアクセスを得られるというものではありません。

主張は次のとおりです:

  • 低権限のチームメンバーが
  • バックエンドのターミナル信頼チェックを満たし
  • チームインフラストラクチャ上でコマンド実行に至ることができる

これは、アプリケーションのRBAC障害から管理ホストへの影響への大きなスコープ変更です。

したがって、権限が低い(ゼロではない)とはいえ、結果は明らかにCriticalです。


それでも報告する価値があった理由

一部の人々は、PR:L で始まる脆弱性を過小評価します。

影響を受ける機能がターミナルアクセスである場合、それは間違いです。

本当の質問は次のとおりではありません:

「攻撃者はすでにログインしていたか?」

本当の質問は次のとおりです:

「バックエンドの認可が間違っている場合、その低権限ユーザーは何に到達できるのか?」

このケースでは、答えは次のとおりでした:

  • ホスト選択データ
  • ターミナルブートストラップの信頼
  • SSHバックアップのPTY実行
  • チームサーバー上でのシェルアクセス

これは、通常のメンバー権限バグをはるかに超えています。


修正分析

最小限の正しい修正は簡単です:

  • POST /terminal/auth および POST /terminal/auth/ips の両方に can.access.terminal を適用する
  • 管理者以外のメンバーが両方のルートから拒否されるようにする
  • 以下のリグレッションカバレッジを追加する:
    • 未認証ユーザーは拒否される
    • 認証済みメンバーは拒否される
    • 認可された管理者と所有者は許可される

これにより、即座の信頼境界の失敗に対処できます。

ローカルの検証パッチでは、これら2つのルートにターミナル認可ミドルウェアを適用することで、メンバーからターミナルへのパスが除去されました。

しかし、より強力な教訓は、バックエンドが攻撃者制御のSSHコマンド文字列をターゲットメタデータの主要ソースとして信頼すべきではないということです。

推奨される強化策は次のとおりです:

  • ターミナルリクエストをサーバー側で認可されたサーバーまたはコンテナ識別子にバインドする
  • コマンドが実行される際に認可を再検証する(WebSocketが開かれたときだけでなく)
  • セキュリティ判断のためにクライアントから提供されるターミナルコマンド構造への依存を減らす

これがターミナル機能に必要な種類の是正です:

  • 即座の欠落した認可を修正する
  • 次に、より深い信頼モデルを強化する

開示

この問題は、GitHubのセキュリティ報告フローを通じて非公開で報告されました。

報告には以下が含まれていました:

  • 認可の不一致
  • 影響を受けるルート
  • リアルタイムバックエンドの信頼パス
  • 動作するローカルラボでの検証
  • リモートシェル出力を示すエンドツーエンドの証明

その後、この問題には次のCVEが割り当てられました:

CVE-2026-34048


このバグが実際に教えること

主な教訓は単純です:

バックエンドのブートストラップチャネルがより弱い状態を信頼している場合、管理者専用のUIは意味をなさない。

それが実際の問題クラスです。

  • ページは正しく保護されている可能性がある。
  • メニューは正しく非表示にされている可能性がある。
  • ターミナル画面は正しくブロックされている可能性がある。

以下の場合、それらはすべて無意味です:

  • WebSocketのブートストラップパスがログイン状態のみをチェックする場合
  • ターミナルバックエンドがそれらのブートストラップ応答を信頼する場合
  • 結果のセッションがホストのコマンド実行に到達できる場合

プラットフォームがインフラストラクチャを管理するようになると、認可の不一致は通常のアクセス制御のミスではなくなります。 それらはインフラストラクチャに影響を与える脆弱性になります。

それが本当の教訓です。


重要なポイント

  • WebSocketのブートストラップエンドポイントは実際のセキュリティ境界である
  • UIのみの認可はターミナル機能には不十分である
  • 低権限ユーザーでも、バックエンドの信頼が間違っていると重大な影響を生み出す可能性がある
  • サーバーメタデータと可視のキーUUIDの列挙により、このバグは実用的になった
  • 深刻度を主張する際には、エンドツーエンドの実行時検証が重要である
  • 正しい修正は、より強力なフロントエンドのゲートではなく、一貫したバックエンド認可である

最後に

この脆弱性は巧妙なペイロードに関するものではありませんでした。

正しい信頼境界を特定することに関するものでした。

Coolifyはターミナルアクセスを管理者専用にすることを意図していました。 しかし、リアルタイムターミナルバックエンドは、ユーザーがログインしているかどうかのみをチェックするルートを信頼していました。

そこから、低権限のチームメンバーがWebSocketターミナルパスを操作し、チームサーバー上でシェル実行に至ることができました。

だからこそ、これがCVE-2026-34048になったのです。

ツールをダウンロード