
Kestraの未認証RCEであるCVE-2026-53576のエンドツーエンド再現とクロスレイヤー検出 — ベースPoCを超えて、よくあるDockerソケットの設定ミスがどのようにコンテナrootをホスト全体の侵害へと変えるかを示す。
Kestraは、オープンソースのワークフローオーケストレーションプラットフォームであり、リクエストに認証情報が必要かどうかを、URLが/configsで終わるかどうかで判断する認証フィルターを出荷していました。これは、1つの無害な公開エンドポイントを公開するためのチェックでした。
このチェックは文字列の末尾のみを確認していたため、URLがたまたまそのように終わるリクエストはすべて認証を完全にスキップしました。これには、任意のコードを作成・実行するエンドポイントも含まれます。 その結果: ネットワーク経由で脆弱なKestraインスタンスに到達できる者は誰でも、認証情報ゼロ、フィッシングなし、パスワード推測なし、権限昇格ステップ不要で、rootとしてコマンドを実行できます。
この演習では、その単一のギャップをセルフホストのラボインスタンスに対してエンドツーエンドで実行しました:
すべての段階は、防御側のテレメトリ (ネットワークIDS、ホストランタイムセキュリティ、Linux audit、およびシステムログ) に対してキャプチャされました。
未パッチの場合のビジネスへの影響: Kestraを実行しているホストの完全な侵害であり、アプリケーションだけでなく、そのホストから到達可能な他のすべてのものにも及びます。
修正: Kestra 1.0.45 / 1.3.21以降にアップグレードしてください (パッチ単体で主要な脆弱性は塞がれますが、昇格と永続化の段階には別個の独立した修正が必要です - アプリケーションコンテナにDockerソケットをマウントしないでください。セクション8を参照)。
本レポートは、Kestra ≤1.3.20におけるCVSS 10.0の未認証リモートコード実行脆弱性であるCVE-2026-53576を文書化したものです。これは、パスサフィックス認証バイパス (AuthenticationFilter.java、endsWith("/configs")) に起因します。
ワークフローの名前空間とIDをconfigsと命名した攻撃者は、認証情報なしで、Kestraコンテナ内でrootとして、任意のシェルコマンドを作成・実行できます。1.0.45および1.3.21で修正されました。同一のバグはCVE-2026-49869としても独立に報告されており、これが実際の野放しの悪用に関連するCISA KEVに掲載された番号です。公開情報源やスキャナーはいずれかを参照する可能性があるため、両方を併記すべきです。
| 脆弱 | Kestra ≤ 1.3.20 (および1.0.x系では1.0.45より前) |
| 修正済み | 1.0.45 / 1.3.21+ |
| CVE | CVE-2026-53576 |
| 双子のアドバイザリ | CVE-2026-49869 - 同一のバグ、CISA KEV掲載 (野放し) |
| 日付 | イベント |
|---|---|
| 2026-06-02 | Kestra 1.3.21リリース。チェンジログが「認証フィルターにおける潜在的な認証バイパス」に言及 |
| 2026-06-03 | Kestra 1.0.45が1.0.x系でリリース |
| 2026-09-02 | CVE-2026-49869 (双子のアドバイザリ) がCISA KEVカタログに追加 |
| 2026-09-22 to 09-24 | 本ラボでの再現、検知構築、およびクロスレイヤー検証 |
セルフホストのホームラボ:
- Debianホスト (ホスト名docker、カーネル6.12.107+deb13-amd64)、
- Docker Engine 29.8.1。
- Kestraは公式のkestra/kestra:v1.3.20イメージとしてデプロイされ、kestra.int.atlasvec.comのCaddyリバースプロキシ経由で到達可能。
- テスト対象のテレメトリスタック: Falco (ランタイム/eBPF、ホストレベル)、
- Suricata 8.0.3 IDS (パッシブSPANミラー)、Splunkへ転送。
何かに触れる前に、ターゲットが実際に脆弱であることと、テレメトリスタックが稼働していることを確認しました。また、攻撃前の状態のスナップショットを取得し、完了後に元に戻せるようにしました。
脆弱なバージョンを実行しているKestra:

コンテナ自体が起動し、到達可能:

ホストにロードされたFalcoのユニット:

Falcoがイベントをアクティブに発行中 (モダンeBPFモード):

Suricataのサービスがアクティブ:

そしてそのeve.jsonがライブイベントを書き込み中:

これは1つではなく、2つの誤りが重なったものです。
第一に、認証フィルターは、リクエストパスの末尾を照合することで、リクエストが認証をスキップできるかどうかを判断します:```java // AuthenticationFilter.java — the vulnerable check, confirmed against the self-hosted v1.3.20 source if (path.endsWith("/configs")) { // treated as a public, unauthenticated path }
そのチェックは、単一の無害なエンドポイントである公開インスタンス設定を露出させるために存在する。`endsWith` は文字列の末尾だけを読むため、1つの安全なパスと、たまたま同じ末尾を持つ他のあらゆるパスとを区別できない。
第二に、Kestra のルーターはそれらの類似パスを、実際の機密性の高いハンドラーへ依然としてディスパッチする。`/api/v1/main/flows/configs` は flow-create ハンドラーに到達する。`/api/v1/main/executions/configs/configs` は execution ハンドラーに到達する。フィルターは両方を公開として通し、ルーターはそのまま実行する。フローの namespace と ID を `configs` と名付ければ、コード実行エンドポイントは `/configs` で終わるようになり、公開パスのフリーパスを継承する。
キャプチャしたリクエストのペアがそれを明示している。認証情報なしの `GET /api/v1/main/flows/search` は `401` を返す。同じ空の認証ヘッダーを付けた `POST /api/v1/main/flows/configs` は `200` を返し、フローを保存する(§5.1 参照)。
## 5. 攻撃シミュレーション
> 以下の各ステップは、それぞれのスクリーンショットとともにキャプチャされている。すべては、リバースプロキシの背後にある自己ホスト型 Kestra インスタンスに対して、私自身の隔離されたホームラボ内で実行されている。
### 5.1 ステージ 1 - 認証バイパス -> Kestra コンテナ内での root
**コントロール :** 認証情報なしの `GET /api/v1/main/flows/search` → `401 Unauthorized`。
通常のルートで認証が強制されていることを確認する。

_____
**植え付け :** 認証ヘッダーなしで `POST /api/v1/main/flows/configs` を送信する。ボディはフロー YAML で、その `namespace` と `flow id` はどちらも `configs` であり、Process タスクランナーを使用する Commands タスクを含む。サーバーは `200 OK` を返し、フローを保存する。それ以外は保護されたルート上の `/configs` サフィックスが、バイパスを引き起こすものである **(セクション 4 参照)。**

**リッスン & 待機** : テスト目的で nc を使った簡単なリスナーを起動し、リバースシェルを捕まえる。

**トリガー / 実行** `POST /api/v1/main/executions/configs/configs`、認証ヘッダーなし → `200 OK`、新しい実行が作成される。

**BaaaaM :** シェルを奪取したが、忘れないでほしい - 我々は「隔離」されており、`root` ではある **が** Kestra docker コンテナの内部であるため、ここから「脱出できないはず」である。「**そう、それが私の考えだった**」

タスクのコマンドは Kestra JVM プロセスの直接の子として実行され、ホスト側のプロセスツリーで確認され、Kestra 自身の実行ログにより正常に完了している。
**Kestra のログダッシュボード**

**Kestra のプロセスツリー**

**結果:** Kestra コンテナ内での root としての未認証リモートコード実行。これが **CVE-2026-53576** の完全で自己完結した証明である。
### 5.2 ステージ 2 - 露出した Docker ソケットを介したエスカレーション(ホームラボ固有、CVE 自体の一部ではない)
ステージ 1 のシェルから、`/var/run/docker.sock` がコンテナにマウントされているのが見つかった - Docker-outside-of-Docker(DooD)パターンであり、Kestra 自身の `Docker` タスクランナーが設定されている場合に一般的である。これは通信相手となるデーモンを必要とするためである。
そのソケットに到達すること自体が、ホストの **root** と等価である。Docker API は、クライアントが生成するコンテナに対して任意のホストバインドマウントやホスト PID/ネットワーク名前空間を構成できるようにし、ソケットの背後にあるデーモンはすでにホスト上で root として実行されている。
これはカーネルやコンテナエスケープのエクスプロイトではない - Docker API が設計通りに動作しているところを、到達されるべきでない場所から到達しただけである。
ソケットを使用して、ホストファイルシステムをバインドし、ホスト PID とネットワーク名前空間を持つ兄弟コンテナを作成し、起動した。
**注:** テスト中に、より静かな第二の変種も現れたが、別途スクリーンショットは撮らなかった。常に新しい兄弟コンテナを作成する代わりに、同じソケットアクセスで、すでに実行中のコンテナに対して `POST /containers/{id}/exec` を実行できるため、コンテナ作成イベントは一切発生しない。この Docker ホストには Kestra と Portainer の両方があり、同じエスケープにどちらでも使用できる。これは検知にとって重要である。新しい特権コンテナの作成に焦点を当てたルールは、この変種を見逃す。
root を確認し、ソケットがあらゆる制限から外れてそこに存在するのを発見する:

Docker デーモンが実際にソケットを通じて到達可能か確認する:

すでにローカルにあるイメージを列挙し、何もプルする必要がないようにする:

最初の試み: ホストファイルシステムをバインドした特権コンテナ:

二度目の試み、今回はホスト PID とネットワーク名前空間を追加:

三度目の試み、マウントされたホストファイルシステムに直接 chroot する:

リスナーを起動し、エスケープシェルがコールバックするポートで待機する:

コンテナを起動する:

**Root、しかし今回はコンテナではなくホストである:**

カーネルバージョンが、コンテナの隔離されたビューではなく、実際のホストと一致する:

残りのセッションのために、適切な対話型シェルにアップグレードする:

### 5.3 ステージ 3 - 永続化、発火を確認
ホスト root シェルから、2つの独立した永続化メカニズムを設定した。
**第一に**、SSH キー。すでに誰がアクセスを持っているか確認した:

次に、新しいキーをブロックするものがないか sshd 自身の設定を確認した:

攻撃者ボックスでキーペアを生成した:

sshd が実際にリッスンしていることを確認した:

公開キーを root の `authorized_keys` に投入した:

そして、対応する秘密キーでログインした:

**PS:** これは元の RCE チェーンとは独立した root アクセスである。Kestra にパッチが当てられても、このキーは依然として機能する。
**第二に**、cron ビーコン。定期的に実行される root レベルのコールバックを投入し、新しいリスナーでテストして、スケジュール通りに実際に発火するか確認した:

**発火した。ホスト上の第二の足場であり、RCE と SSH キーの両方から独立している。**
### 5.4 検証済みキルチェーンタイムライン。
以下のタイムラインは異なる: 独立した防御側テレメトリ(ネットワーク IDS + ホストランタイムセキュリティ)のみから完全に再構築され、実際の Splunk データに対してライブで取得・検証されたものである。
**主要 RCE - ネットワークが配送を検知し、ホストが実行を確認、その間隔は 103 秒:**
| 時刻 (EDT) | レイヤー | イベント |
| ------------ | ------------------ | -------------------------------------------------------------------------------------------- |
| 02:46:09.778 | ネットワーク (Suricata) | この正確な CVE に対する公開 ET シグネチャが発火 |
| 02:47:52.277 | ホスト (Falco) | Kestra コンテナ内でリバースシェルを確認、正確なコマンドとコンテナ ID をキャプチャ |
**エスカレーション - ネットワークとホストが、同じイベントの異なる部分をそれぞれ独立に裏付ける:**
| 時刻 (EDT) | レイヤー | イベント |
| ------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| 03:48:55.503 | ホスト (Falco) | エスカレーションコンテナからのリバースシェル |
| 03:51:57.360 | ネットワーク (Suricata) | TCP フロー **および** コンテンツベースのアラート - `id` の実行時に、文字列 `uid=0(root)` がホストから平文で出ていくのが見られた |
## 6. 検知エンジニアリング
実際にキャプチャしたテレメトリに対して検知を構築し、それぞれをリプレイに対してテストした。マトリクスは、私が始める前にカバレッジが存在した場所と、存在しなかった場所を示している。
### 6.0 検知カバレッジマトリクス
| ステージ | ネットワーク (Suricata) | ホスト (Falco) | ホスト (auditd/journald) | ステータス |
| --- | --- | --- | --- | --- |
| 初期エクスプロイトリクエスト | 公開 ET シグネチャが発火 | アプリ層の可視性なし | - | カバー済み(既存) |
| RCE 実行 | - | ネイティブルール、T1059 タグ付き | - | カバー済み(既存) |
| Docker ソケットエスカレーション(この手法) | - | ギャップ: 結果として生じるシェルのみを捕捉し、ソケット悪用 API 呼び出しは捕捉しない | EXECVE レコードが正確な `curl --unix-socket` 呼び出しをキャプチャ | ギャップを発見、auditd + カスタム Falco ルールで閉鎖 |
| エスカレーション影響確認 | 漏洩した `id` 出力に対するコンテンツアラート | 同じ汎用シェルルール | - | カバー済み(既存、クロスレイヤー) |
| SSH 永続化 | - | - | journald: 完全な PAM ライフサイクルとキーフィンガープリント | カバー済み(ホストのみ) |
| Cron 永続化 | - | - | journald と linux_audit、2つのソース、正確な 5 分間隔 | カバー済み(ホストのみ) |
ギャップは docker ソケットエスカレーションである。Falco のデフォルトルールは、侵害されたコンテナが生成するシェルを捕捉するが、安定したデフォルトセットには、`/var/run/docker.sock` に到達して Docker API を直接操作するプロセスをフラグ付けするものは何もない。特権コンテナの起動に触れるルール、`Launch Privileged Container` と `Launch Sensitive Mount Container` は、`incubating` と `sandbox` の成熟度で提供されるため、デフォルトルールセットはそれらもロードしない。私は auditd 相関検索(検知 03)とカスタム Falco ルール(§6.3)でギャップを閉じた。
### 6.1 Splunk - 5つの相関検索、デプロイ済みかつスケジュール済み
5つすべてが Splunk でライブ実行されている(`*/5 * * * *`、アラートトラッキング有効、フィールドごとのスロットリング)。書かれただけでテキストとして放置されているわけではない。完全な SPL、正確な FP ノート、重大度、MITRE タグ、および各々の対応ランブックは `detections/splunk/*.spl` にある。以下のステータステーブルは、各々のライブテスト結果であり、私が見つけて修正した実際のバグも含む。
| # | 検知 | MITRE | ステータス |
| --- | ---------------------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| 01 | ネットワークエクスプロイトシグネチャ(Suricata ET アラートを消費) | T1190 | **発火** - 履歴リプレイで確認、以降の新規イベントなし(現在のルックバック外) |
| 02 | ホスト RCE 実行(Falco redirect-to-network ルール) | T1059 | **発火** - 履歴リプレイで確認 |
| 03 | Docker ソケット悪用(auditd、ギャップクローザー) | T1610, T1611 | **ライブスケジューラー自体で発火** - 実際の `*/5 * * * *` 実行で `triggered_alert_count: 1` を確認、手動テストだけでなく |
| 04 | SSH root ログイン永続化 | T1098.004, T1021.004 | **発火** - 履歴リプレイで確認 |
| 05 | Cron ビーコン永続化 | T1053.003 | **私が見つけてライブで修正したバグとともにデプロイ。** `-10m` のディスパッチウィンドウは、`distinct_intervals >= 3` 閾値が必要とする 3 つの 5 分バケットのうち 2 つしか保持しておらず、ビーコンが実データで依然として実行中であるにもかかわらず発火できなかった。`-30m` に広げて再デプロイした - そしてスケジューラーはそれ以来 53 回発火しているので、修正は有効である。 |
検知 03 の役割分担は意図的である。SPL で Suricata 自身のシグネチャロジックを再実装したり、Falco にそれが作られていないソケットレベルの手法を捕捉させようとするのではなく、ここでの SIEM レイヤーは、正確な `curl --unix-socket` 呼び出しの auditd の EXECVE レコードを消費する - この特定の手法に対して最も信頼できると証明されたテレメトリソースである。
1. **検知 01** - ET シグネチャの発火(`suricata:eve` アラート):```spl
index=main sourcetype=suricata:eve event_type=alert
alert.signature="ET WEB_SPECIFIC_APPS Kestra Unauthenticated Remote Code Execution (CVE-2026-53576)"
| stats count min(_time) as first_seen max(_time) as last_seen
values(src_ip) as source_ips
by dest_ip dest_port
| eval first_seen=strftime(first_seen,"%Y-%m-%d %H:%M:%S")
| eval last_seen=strftime(last_seen,"%Y-%m-%d %H:%M:%S")

Detection 02 - Falco の redirect-to-network ルールをコンテナごとに分割したもの。送信元 IP は Kestra コンテナのブリッジアドレス(172.17.0.3、ポート 4489 での primary RCE)からホスト自身(172.66.66.67、ポート 4491 でのエスカレーション)へと変化する - コンテナからホストへのエスカレーションが可視化されている - 一方で宛先は一定のままである。攻撃者のリスナー 172.66.66.125 である:

Detection 03 - curl --unix-socket docker.sock の auditd EXECVE レコード:

Detection 04 - journald の root SSH ログイン、鍵フィンガープリントを取得:

Detection 05 - 隠しドットファイルの cron ビーコン(/usr/local/bin/.sysmon)が root として正確に 5 分間隔で実行されている:約 6.5 時間(04:30-11:00 EDT)にわたって 79 個の異なる間隔。distinct_intervals >= 3 のしきい値が、定期的なビーコンと単発の cron ジョブを区別するものである:

5 つすべてがスケジュール済み保存検索(*/5 * * * *)としてデプロイされている:

cron スケジューラがこれらを実際に実行していることの証明(単に存在するだけでない):5 つすべてが 54 回実行された。Detection 03 は 1 回発火し(docker-socket の悪用、06:35 EDT)、Detection 05 は 53 回発火した(まだ活動中の cron ビーコン)。Detection 01/02/04 は 0 回の発火を示している。これらは一度きりの過去のイベント(exploit リクエスト、RCE、SSH ログイン)であり、-10m のルックバックから外れて古くなっているためである。一方、稼働中または再発するインスタンスであれば依然としてアラートが出るはずである:

/dev/tcp/ リバースシェルパターン - primary RCE とエスカレーションのコールバックの両方で使用された。SigmaHQ はこれに対するルールを提供している:"Suspicious Reverse Shell Command Line"(id 738d9bcf-6999-4fdb-b4ac-3033037db8ab、Nextron Systems の Florian Roth 作)。そのキーワードの 1 つが bash -i >& /dev/tcp/ であり、これはまさに我々のキャプチャに現れたものである。
そこで私はそのルールを変更なしで取り込み(detections/sigma/lnx_shell_susp_rev_shells.yml)、そのキーワードを Detection 02 がすでにキャプチャした同じ Falco イベントに対して確認した。Sigma は単独で「発火」するものではない - それはポータブルなシグネチャであり、稼働するエンジンではない - しかし、教科書的な例ではなく、この実行からの実際のテレメトリに対してそのキーワードが一致することを示すことはできる。
公開 SigmaHQ ルール "Suspicious Reverse Shell Command Line" - その bash -i >& /dev/tcp/ キーワードを Detection 02 と同じ実際のイベントに対して適用:

detections/falco/docker_socket_abuse.yaml - 稼働中の Falco インスタンスにデプロイされ、実際のリプレイで発火することを確認済み、2026-09-24T10:27:29Z。
Falco のデフォルトルールセットはこれをカバーしていない。プロセスが /var/run/docker.sock に到達することを検出するのは新しいアイデアではない - Sysdig 自身の Falco の例ではソケットパスへの open_write を監視することでこれを行っている - しかし、出荷されるデフォルトセットにはそのようなルールは存在せず(プロジェクトにはそのためのオープンなリクエストがある、falcosecurity/falco #2940)、隣接する唯一のデフォルトルールは docker/kubectl CLI のみを捕捉し、生の curl --unix-socket は捕捉しない。
問題点:その標準的なソケットへの open_write アプローチはこのセットアップでは発火しなかった - modern_bpf とパッシブミラーでは、ソケットには open() ではなく connect() を経由して到達する。そこで私は代わりにプロセス生成時のコマンドラインでマッチする(spawned_process + proc.cmdline contains "docker.sock")。これは Falco がここで確実に処理しているのと同じイベントクラスである。呼び出しごとに 2 回発火する - シェルラッパーと curl リーフ - 完全なコンテキスト付きで:```
priority=Critical, container_id=d417e027d444, image=kestra/kestra:v1.3.20, user=root, cmdline="curl -s --unix-socket /var/run/docker.sock http://localhost/version", tags=[T1610, T1611]
カスタム Falco ルールの発火 - 「Unexpected Process Accessing Docker Socket」(T1610/T1611):

発火した標準の Falco ルール - デフォルトセットには docker-socket ルールが存在せず、これがギャップである:

### 6.4 Suricata - 既存の公開カバレッジ、カスタムルールは保留
主要なエクスプロイトのネットワーク層は、公開されている Emerging Threats シグネチャ `ET WEB_SPECIFIC_APPS Kestra Unauthenticated Remote Code Execution (CVE-2026-53576)` によってすでにカバーされており、これはフェーズ 2 中に実際のトラフィックで発火した。
以下は、ネットワーク層で見られた同じバイパスであり、私は脆弱性のパターンからクエリを構築した。`flows` または `executions` エンドポイント上の `/configs` で終わるパスを持つすべてのリクエストは `200` を返したが、通常のルート(`/flows/search`)は期待どおり `401` を返した。
`Attacker IP (XFF)` 列は実際の HTTP オリジンであり、`X-Forwarded-For` ヘッダーから読み取ったものである: `10.10.10.106`、Burp を実行している私の Mac である。Suricata 自身の `src_ip` はリバースプロキシのホップ(`172.66.66.1`)しか見えていない。これは、後にリバースシェルを捕捉し SSH ログインを行った `172.66.66.125` の Kali ボックスとは別のマシンであるため、HTTP エクスプロイトとコールバックは別々のホストから来ていたことになる。

### 6.5 ダッシュボード
`cve_2026_53576_kill_chain` は Splunk にデプロイされており、以下を含む: ヘッドライン KPI(検知レイヤー、ATT&CK テクニック、デプロイ済み検知、永続化メカニズム)、テレメトリレイヤー別に色分けされた攻撃タイムラインの縦棒グラフ、ステージごとのライブ証拠数を含む MITRE ATT&CK キルチェーンマップ、§5.4 のネットワークとホストを相関させたタイムライン、スケジュールされた保存検索による検知カバレッジ、docker-socket テクニックの内訳、そしてログからライブで取得した侵害指標テーブル。
- KPI、攻撃タイムラインのグラフ、ATT&CK マップの冒頭:

- ATT&CK マップの残り、相関させたキルチェーン、docker-socket の内訳の隣にある検知カバレッジ、そして IOC テーブル:

## 7. ATT&CK マッピング
| 戦術 | テクニック | 証拠 |
| -------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Initial Access | T1190 - Exploit Public-Facing Application | Control/plant/execute リクエスト(§5.1)、Suricata ET シグネチャの発火、§5.4 |
| Execution | T1059.004 - Command and Scripting Interpreter: Unix Shell | Kestra `Commands` タスク、ホストプロセスツリー(`07-kestra-process-tree.png`)、Falco ルール、§6.1 検知 02 |
| Command and Control | T1095 - Non-Application Layer Protocol | 生の `/dev/tcp/` TCP リバースシェル - アプリケーション層の C2 フレーミングは使用されていない |
| Discovery | T1613 - Container and Resource Discovery | ソケット経由の Docker イメージ列挙(`10-docker-images-enum.png`) |
| Privilege Escalation | T1610 - Deploy Container | Docker API 経由の兄弟コンテナの作成/起動(`11`–`15`)、auditd EXECVE レコード、§6.1 検知 03 |
| Privilege Escalation | T1611 - Escape to Host | ホスト root の確認、hostname/kernel の一致(`16`、`17`) |
| Persistence | T1098.004 - Account Manipulation: SSH Authorized Keys | `/root/.ssh/authorized_keys` への鍵の埋め込み(`23`) |
| Lateral Movement | T1021.004 - Remote Services: SSH | 鍵ベースの root ログインの成功(`24`)、journald、§6.1 検知 04 |
| Persistence | T1053.003 - Scheduled Task/Job: Cron | Cron ビーコン、スケジュールどおりの発火を確認(`25`)、§6.1 検知 05 |
## 8. 修復とハードニング
**主要な修正。** Kestra 1.0.45(1.0.x 系)または 1.3.21 以降(1.3.x 系)にアップグレードする。これだけで認証バイパス - この演習のステージ 1 - が塞がり、適用後はさらなる補償コントロールを必要としない唯一の修正である。詳細は [GHSA-2q47-568g-9h4f](https://github.com/kestra-io/kestra/security/advisories/GHSA-2q47-568g-9h4f) を参照。
**即時のパッチ適用が不可能な場合**、影響の大きい順に補償コントロールを示す:
1. **リバースプロキシによる強制** - 脆弱なフィルターは生のパスサフィックスでのみ失敗するため、Kestra の前段にあるリバースプロキシ(このラボでは Caddy)が、`/api/v1/*/(flows|executions)/.*` に一致する任意のパスに対して、その末尾が何であっても独立して認証を強制でき、アプリケーションのバグが到達できない層でバイパスを塞ぐことができる。
2. **Docker ソケットマウントの制限** - これは Kestra のパッチとは独立して、ステージ 2〜3 を完全に塞ぐ。`/var/run/docker.sock` を Kestra コンテナにバインドマウントしないこと。`Docker` タスクランナーが本当に必要な場合は、完全なデーモンアクセスを付与する代わりに、特定の API 呼び出しを許可リスト化するスコープ付きソケットプロキシ(例: `docker-socket-proxy`)を使用すること - §5.2 で実証したとおり、ソケットへの完全なアクセスはホスト root と等価である。
3. **SSH のハードニング** - 永続化チェーンの最初のメカニズムは、そもそも鍵ベースの SSH 経由で root に到達可能であることに依存していた。`PermitRootLogin no`(または root に bastion/MFA を要求する)であれば、初期 RCE に関係なくその特定の永続化パスをブロックできたはずである - この CVE とは独立して実施する価値がある。
4. **暫定的な検知カバレッジ** - この演習中にデプロイおよび検証された Splunk 相関検索とカスタム Falco ルールは、パッチ適用が予定される間、この特定のチェーンの各ステージに対する暫定的なカバレッジを提供する。
**インシデント後の衛生管理**、このパターンがすでに悪用されていることが判明した場合: 単なるアプリケーション侵害ではなく、完全なホスト侵害として扱うこと - Kestra インスタンスがアクセスできたすべての資格情報とシークレット(KV ストアのエントリ、下流システムの接続資格情報)をローテーションし、Kestra 自身のアクセスだけに留めないこと。
**実環境での状況。** この同じバグに対する双子のアドバイザリである `CVE-2026-49869` は、CISA の KEV カタログに掲載されており、観測された暗号通貨マイニングおよびクラウド資格情報窃取キャンペーンと関連付けられている。`CVE-2026-53576`(本レポート)には独自の KEV 掲載はないが、同一の脆弱性である。2 つの CVE 番号のうち片方のみを追跡する脆弱性管理ツールは、露出を過少報告する可能性がある。
## 9. 参考文献
- Kestra セキュリティアドバイザリ - [GHSA-2q47-568g-9h4f](https://github.com/kestra-io/kestra/security/advisories/GHSA-2q47-568g-9h4f)(CVE-2026-53576、本レポートの主要な情報源)
- 双子のアドバイザリ - [GHSA-5vc5-wxxq-3fjx](https://github.com/kestra-io/kestra/security/advisories/GHSA-5vc5-wxxq-3fjx)(CVE-2026-49869、同一のバグ、CISA KEV 掲載)
- CVE.org - [CVE-2026-53576](https://www.cve.org/CVERecord?id=CVE-2026-53576)、[CVE-2026-49869](https://www.cve.org/CVERecord?id=CVE-2026-49869)
- CISA Known Exploited Vulnerabilities Catalog - https://www.cisa.gov/known-exploited-vulnerabilities-catalog(CVE-2026-49869 のエントリ、2026-09-02 追加)
- 修正済みリリース、両方とも存在が確認されタグ付け済み - [v1.3.21](https://github.com/kestra-io/kestra/releases/tag/v1.3.21)(2026-06-02、チェンジログに「potential authentication bypass in the authentication filter」への明示的な言及あり)、[v1.0.45](https://github.com/kestra-io/kestra/releases/tag/v1.0.45)(2026-06-03)
- Docker ソケットエスカレーション技法(§5.2) - [HackTricks: Docker Breakout / Privilege Escalation](https://hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html)、[Trail of Bits: Understanding Docker Container Escapes](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)、[MindPatch: Docker Escape](https://www.mindpatch.net/posts/docker-escape/)
- Sigma ルール(§6.2) - 自作せずに使用した公開ルール: [SigmaHQ "Suspicious Reverse Shell Command Line"](https://github.com/SigmaHQ/sigma/blob/master/rules/linux/builtin/lnx_shell_susp_rev_shells.yml)(id `738d9bcf-6999-4fdb-b4ac-3033037db8ab`、Florian Roth / Nextron Systems)、[Detection Rule License 1.1](https://github.com/SigmaHQ/sigma/blob/master/LICENSE.Detection.Rules.md) の下で使用
- Falco ルール(§6.3) - docker-socket のギャップは上流で未解決のリクエストである([falcosecurity/falco #2940](https://github.com/falcosecurity/falco/issues/2940))。カスタムルールは [Sysdig の Docker + Falco の例](https://www.sysdig.com/blog/docker-falco-security)のパターンに従っている