CyberFix Note
脆弱性・CVE解説

KestraのCVE-2026-49869。末尾一致で認証を判定したフィルタが認証なしのRCEになる

対象の目安: ワークフロー基盤を運用する開発者と基盤担当 / 実務

ソウ攻撃・脆弱性リサーチ担当
・ 約29分で読めます
KestraのCVE-2026-49869。末尾一致で認証を判定したフィルタが認証なしのRCEになる

APIのパスが /configs で終わっているかどうかを endsWith() で判定していた。この1行の判定方法が、認証をまるごと素通しにしました。オープンソースのワークフローオーケストレーション基盤Kestraに見つかったCVE-2026-49869です。CVSSは10.0、CISAは2026年9月2日にKnown Exploited Vulnerabilities(KEV)カタログへ追加し、是正期限を3日後の2026年9月5日としました。

判定に使われたのは、パスの完全一致ではなく末尾一致でした。公開してよい設定取得用のエンドポイントだけを認証の対象外にする意図でしたが、末尾が configs になるパスであれば何であれ、その手前が何であっても認証を飛ばして通過します。そしてKestraはスクリプト実行用のプラグインを既定で同梱しているため、認証を抜けた先でワークフローを作って走らせれば、そのままワーカーコンテナ内でのコマンド実行になります。

この記事は、Kestraを自社で運用している開発者と基盤担当に向けて、GitHub Security Advisory、NVD、CISAのKEVカタログ、Kestraの修正コミットとタグ、Microsoftのインシデント調査という一次情報をもとに、機構と対応を整理します。攻撃を成立させる具体的なリクエストや動作するコードは扱いません。挙動の確認を行う場合は、自分が管理する環境か、書面で許可を得た環境に限ってください。他人の管理するシステムへ許可なくリクエストを送る行為は、日本では不正アクセス行為の禁止等に関する法律や刑法の電子計算機損壊等業務妨害に触れる可能性があります。記述は執筆時点(2026年9月7日)に確認できた範囲に限ります。

KEVカタログの登録内容と3日という是正期限

CISAは2026年9月2日、7件の脆弱性をKEVカタログへ追加しました。CVE-2026-49869はそのうちの1件です。同じ日にはSangoma Switchvox、Starlette、LiteLLM、JFrog Artifactory、SonicWall SMA1000の各CVEが並んでいます。

執筆時点で取得できるKEVカタログのJSONは、catalogVersionが2026.09.04、収録件数が1695件です。CVE-2026-49869の登録内容は次のとおりです。

項目
cveIDCVE-2026-49869
vendorProject / productKestra / Kestra OSS
vulnerabilityNameKestra OSS OS Command Injection Vulnerability
dateAdded2026-09-02
dueDate2026-09-05
cwesCWE-78, CWE-184, CWE-287, CWE-918
knownRansomwareCampaignUseUnknown
forensicTriageYes

追加から是正期限までが3日しかない点と、forensicTriageがYesである点が、このエントリの特徴です。両方ともCISAのBOD 26-04にひもづきます。この拘束的運用指令は、資産が公開されているか、KEVに載っているか、悪用が自動化できるか、技術的影響が部分的か全面的かという4つの判断点で是正期限を決めます。最短の3日は、公開資産でKEV収録済み、悪用が自動化可能、資産の完全な掌握に至るという条件がすべて揃った場合です。この区分では、期限内の是正または緩和に加えて、当該資産のフォレンジックトリアージを実施して侵害の有無を判断することが求められます。

NVDに載っているCISA CoordinatorのSSVC評価(2026年9月1日時点)は、exploitationがactive、automatableがyes、technicalImpactがtotalです。3つとも最も重い側に振れており、KEVのdueDateが3日になった理由と整合します。

期限そのものは米国の連邦文民行政機関に対する行政上の要求であり、日本の組織を法的に拘束するものではありません。日本の組織にとって読み取るべきは、CISAが実際の悪用を確認したと判断したこと、そして自動化された悪用で資産を完全に掌握されうるとCISAが評価したことです。定例の更新サイクルに載せる種類の脆弱性ではないという判断材料になります。

KEVとEPSSを日々の優先度付けにどう組み込むかは、次の記事で整理しています。

あわせて読みたい

脆弱性対応の優先順位付け。CVSSだけに頼らないEPSSとCISA KEVの使い方

endsWithによる末尾一致が認証を素通しにする機構

Kestra OSSの認証は、AuthenticationFilter というMicronautのHTTPフィルタが担っています。@Filter("/api/v1/**") が付いており、APIの全パスを通過点にしています。ここで、初期セットアップ時に使う公開設定エンドポイントだけは認証の対象外にする必要がありました。

修正前の判定はこうなっていました。

// 修正前(v1.3.20)の AuthenticationFilter.java より抜粋
boolean isConfigEndpoint = request.getPath().endsWith("/configs")
    || ((request.getPath().endsWith("/basicAuth") || request.getPath().endsWith("/basicAuthValidationErrors"))
        && !basicAuthService.isBasicAuthInitialized());

if (isConfigEndpoint || isOpenUrl || isManagementEndpoint(request)) {
    return chain.proceed(request);
}

endsWith("/configs") は、パス全体が公開エンドポイントかどうかではなく、パスの末尾が /configs かどうかだけを見ます。意図されていた対象は GET /api/v1/configs と、テナントを含む形の設定取得だけでした。しかし末尾一致である以上、最後のセグメントが configs でありさえすれば、その手前のパスが何を指していても条件が成立します。

Kestraのリソースは、名前空間やフローの識別子をパスの一部として受け取ります。つまり、リソース名として configs を指定すれば、そのリソースを操作するAPIパスの末尾は /configs になります。フィルタはそれを公開設定エンドポイントだと判断し、認証を行わずに次のハンドラへ渡します。

GitHub Security Advisoryは、この形で認証を迂回できる操作として次の種類を挙げています。

迂回される操作攻撃者にとっての意味
フローの作成と上書き任意の内容のワークフローを認証なしで置ける
フローの実行の起動置いたワークフローを認証なしで走らせられる
KVストアへの書き込み任意のキーと値を書き込める
フローとダッシュボードの削除構成を壊せる
ログの削除実行の痕跡を消せる

アドバイザリは範囲の限界も明記しています。迂回が成立するのは、パスの最後のセグメントが文字どおり configs であるリソースに限られます。ただし攻撃者はその名前のフローを認証なしで作成できるため、この制約は実際の悪用を妨げません。

この構図は、認証と認可の判定をパスの文字列照合に依存させたときの典型的な壊れ方です。認証の要否を「どのエンドポイントか」ではなく「パス文字列がある形をしているか」で決めると、リソース名を攻撃者が選べる設計と組み合わさった瞬間に前提が崩れます。

認証と認可を分けて考える整理は、次の記事で扱っています。

あわせて読みたい

認証と認可の違い。Authentication と Authorization を基礎から整理する

GHSA-5vc5-wxxq-3fjxは2026年6月3日に公開され、深刻度をCriticalとしています。影響を受けるパッケージは kestra(io.kestra)、影響を受けるバージョンは1.3.20以下、修正版は1.0.45と1.3.21です。該当箇所として webserver/src/main/java/io/kestra/webserver/filter/AuthenticationFilter.java の49行目を挙げ、endsWith() を完全一致のかわりに使ったことが原因だと述べています。CVSS v3.1のベクトルはCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:Hでスコアは10.0、CWEはCWE-78、CWE-184、CWE-287、CWE-918です。報告者としてVasco0x4が記載されています。

認証バイパスがそのままRCEになる理由

認証の迂回だけであれば、影響はその製品が守っていたデータの範囲で止まります。CVE-2026-49869が10.0になったのは、迂回した先にあるのがワークフローの定義と実行という機能だったからです。

ワークフローオーケストレーション基盤は、外部のシステムを呼び出したりスクリプトを走らせたりすることを目的として作られています。アドバイザリによれば、Kestraは既定の構成でスクリプト実行プラグインを同梱しており、シェル、Python、Node.jsなどのタスク型が使える状態にあります。既定のインストールでは80を超えるスクリプト系プラグインが利用可能だとも記載されています。

したがって成立する流れは単純です。認証なしでフローを1つ置き、認証なしでそれを起動すると、ワーカーがタスクを実行します。アドバイザリは、実行がワーカーコンテナ内で uid=0(root) として行われることを確認したと記載しています。KEVの脆弱性名がOS Command Injection Vulnerability、登録CWEの筆頭がCWE-78になっているのは、この結果を指しています。

OSコマンドインジェクションという分類そのものの成り立ちは、次の記事で扱っています。

あわせて読みたい

OSコマンドインジェクションの仕組みと根本対策。シェルに渡さず引数を分離する

アドバイザリは副次的な影響としてサーバサイドリクエストフォージェリも挙げています。Kestraのテンプレートエンジンが持つHTTP取得用の関数にURIの絞り込みが無いため、認証バイパスと組み合わせると内部ネットワークやクラウドのメタデータエンドポイントへ到達しうるという内容です。KEVに登録されたCWEにCWE-918が含まれているのは、この経路を反映したものです。

コンテナの権限については、アドバイザリの検証環境とMicrosoftが観測した実環境で条件が違っています。アドバイザリは、検証したワーカーコンテナがrootで動いていたものの CAP_SYS_ADMIN を持たず /var/run/docker.sock もマウントされていなかったため、Dockerソケット経由のホストへの脱出は確認していないと明記しています。一方でMicrosoftが調査した環境では、マウントされたDockerソケットにアクセスされ、他のコンテナの環境変数配列が読み出されていました。

この差が生まれる理由は、Kestraの公式クイックスタートが示すdocker runコマンドを見ると分かります。そこには --user=root-v /var/run/docker.sock:/var/run/docker.sock が含まれています。手元で試すための手順をそのまま本番へ持ち込んだ環境では、Dockerソケットが最初からコンテナの中に見えている状態になります。

コンテナに与える権限をどこまで絞るかという整理は、次の記事で扱っています。

あわせて読みたい

コンテナ(Docker)セキュリティの基礎と実務で効く守り方

影響を受けるバージョンと影響を受けない構成

NVDが登録している影響範囲は、1.0.45未満、および1.1.0以上1.3.21未満の2区間です。GitHub Security Advisoryの表記は1.3.20以下で、修正版は1.0.45と1.3.21です。

ここで注意が要るのは、修正が入っている系列と入っていない系列があることです。GitHub上の各タグのソースを確認した限り、状況は次のとおりです。

系列執筆時点の最新タグこの脆弱性の修正
1.0系v1.0.59(2026-09-02)1.0.45で修正済み
1.1系v1.1.20(2026-05-26)修正版なし。末尾一致のまま
1.2系v1.2.24(2026-07-07)修正版なし。末尾一致のまま
1.3系v1.3.37(2026-09-02)1.3.21で修正済み

v1.2.24は2026年7月7日の公開で、アドバイザリの公開より1か月以上あとですが、AuthenticationFilter.java の該当行は request.getPath().endsWith("/configs") のままです。1.1系と1.2系を使っている場合、その系列の最新へ上げても修正は入りません。1.3系へ移すか、長期運用向けの1.0系の最新へ移す判断が必要になります。

なお1.0.45については、GitHubのリリース一覧に項目が見当たらず、タグのみが存在します。タグが指すコミットの日付は2026年6月3日です。リリースノートで探すと見つからないため、タグまたはコンテナイメージのタグで確認してください。

影響を受けない構成もあります。修正前の AuthenticationFilter には @Requires(property = "micronaut.security.enabled", notEquals = "true") という注釈が付いており、ソース中のコメントは「don't add this filter in EE」と書かれています。エンタープライズ版は別の認証機構を使うため、このフィルタ自体が読み込まれません。KEVカタログの製品名がKestraではなくKestra OSSになっているのも、この区別を反映したものだと読めます。

逆に言えば、Kestra OSSでBasic認証を使っている構成はほぼすべて該当します。Kestraはバージョン0.24.0でOSSのBasic認証を必須化しており、公式ドキュメントは enabled フラグが無視されるようになったと説明しています。認証を有効にしているから安全という前提は、この脆弱性には当てはまりません。

アドバイザリは到達性についても明記しています。インスタンスがインターネットに面している必要はなく、待ち受けポートへネットワーク的に到達できる相手であれば成立します。社内ネットワークにだけ置いてあるという理由での据え置きは、成立しません。

NVDのCVE-2026-49869は2026年6月26日に公開され、執筆時点のvulnStatusはAnalyzedです。説明文は、1.0.45と1.3.21より前のKestra OSSのAuthenticationFilterが request.getPath().endsWith("/configs") で公開設定エンドポイントをBasic認証から除外していたこと、これが完全一致ではなく末尾一致であるため最後のセグメントがconfigsになる任意のAPIパスが認証を完全に迂回すること、Kestraがスクリプト実行プラグインを既定で有効にして同梱しているためワーカーコンテナ内でrootとしての認証不要なリモートコード実行に直結することを述べています。掲載されているCVSS v3.1はGitHubが付与したSecondaryの10.0で、NVD自身の一次評価は掲載されていません。cisaExploitAddは2026-09-02、cisaActionDueは2026-09-05です。

稼働中のインスタンスの版と露出を確かめる

該当判定は、動いているKestraのバージョンと、そのポートにどこから届くかの2つを見ます。

バージョンの確認には、認証なしで応答する GET /api/v1/configs が使えます。このエンドポイントは設計上の公開エンドポイントで、Kestraのソースを読むと、インスタンスのUUID、エディション、バージョン、コミットIDとその日付などを返します。自分のインスタンスに対して実行すれば、稼働中の版がそのまま得られます。

# 自組織のインスタンスに対してのみ実行する
curl -s http://<自分のkestra>:8080/api/v1/configs | jq '{version, edition, commitId}'

# コンテナのイメージタグから確認する場合
docker ps --format '{{.Names}}\t{{.Image}}\t{{.Ports}}' | grep -i kestra
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}' | grep -i kestra

同じことは、そのポートに到達できる相手なら誰でもできます。バージョン情報が認証なしで取れる状態は、攻撃者にとっての事前調査を容易にします。露出の確認をあわせて行う理由がここにあります。

# 待ち受けの確認。0.0.0.0 で待っていないか
ss -lntp | grep -E ':8080|kestra'

# Dockerのポート公開範囲。ホスト側が 0.0.0.0 になっていないか
docker inspect <container> --format '{{json .NetworkSettings.Ports}}'

# Dockerソケットがワーカーへマウントされていないか
docker inspect <container> --format '{{json .Mounts}}' | grep -o docker.sock

クラウドで動かしている場合は、セキュリティグループやファイアウォールの受信規則、ロードバランサのリスナ、Ingressの公開範囲を順に確認します。社内からしか見えないつもりでも、VPNの分割トンネル、開発用に開けた一時的な規則、ポートフォワードといった経路が残っていることがあります。

対処の手順

  1. 1

    稼働中のバージョンを確認する

    GET /api/v1/configs の応答、またはコンテナのイメージタグから、実際に動いている版を確認します。開発環境ではなく本番で動いている値を見ます。1.0系なら1.0.45以上、1.3系なら1.3.21以上が修正済みです。1.1系と1.2系は、その系列の最新でも修正が入っていません。
  2. 2

    修正版へ更新する

    1.0系を使っているなら1.0系の最新へ、それ以外は1.3系の最新へ上げます。系列をまたぐ場合は各系列の移行ガイドと変更点を確認し、フローの互換性を検証環境で先に確かめてください。更新後は再度 /api/v1/configs でバージョンを確認します。
  3. 3

    すぐに更新できない場合は到達経路を絞る

    インターネットからの直接到達を遮断し、待ち受けをループバックか管理用セグメントに限定します。前段にリバースプロキシを置き、そこで認証を必須にする構成も緩和になります。ネットワーク的に届く相手であれば成立する脆弱性であるため、社内からの到達経路も同時に絞ります。
  4. 4

    オープンURL設定を見直す

    kestra.server.basic-auth.open-urls に指定した値は前方一致で認証の対象外になります。広すぎる接頭辞を指定していないかを確認し、必要な最小限まで削ります。設定キーの詳細は公式のSecurity and Secretsのドキュメントに記載があります。
  5. 5

    侵害の有無を調べる

    フローの一覧に身に覚えのない定義がないか、実行履歴に想定外の実行が残っていないか、KVストアに見覚えのないキーがないかを確認します。ワーカーが動くホストとコンテナについて、外部への通信、CPU使用率の異常、一時ディレクトリ配下の実行ファイルもあわせて見ます。
  6. 6

    露出していた期間の資格情報を入れ替える

    ワーカーの環境変数、Kestraのシークレットバックエンド、Dockerソケット経由で読めた他コンテナの環境変数に入っていた資格情報を洗い出し、入れ替えます。クラウドのメタデータエンドポイントへ到達しうる構成であれば、インスタンスに紐づく一時認証情報も対象です。

注意

更新の適用と侵害調査は別の作業です。更新するとワーカーのコンテナが作り直され、揮発性の証跡が失われることがあります。3日という是正期限にフォレンジックトリアージが併記されているのは、この順序の問題を含んでいます。長期間インターネットに露出していた本番インスタンスでは、更新の前にコンテナのプロセス一覧、ネットワーク接続、一時ディレクトリの内容を保全しておくと後の判断が変わります。

観測された攻撃後の活動

Microsoftは2026年8月26日に公開した調査で、AIまわりの基盤3種を狙った侵害を報告しています。そのうちの1件がKestraの環境で、CVE-2026-49869の悪用による初期侵入だった可能性が高いと評価しています。攻撃者はログイン機構を迂回して悪意あるワークフローを定義し、ワーカー側でシェルスクリプトを実行させたという内容です。

観測された流れは4段階です。1段目はワークフロー起点のシェル実行で、短い間隔で2つのセッションが記録されています。2段目は、マウントされたDockerソケットへのアクセスによるコンテナのメタデータと環境変数配列の読み出しです。3段目はマイナーの設置で、公開されている配布元からの取得、展開、バイナリの改名、バックグラウンド実行、マイニングプールとの通信が確認されています。あわせてRandomXやXMRigに典型的なCPUチューニングの挙動と、一時パス周辺での権限の絞り込みや不変属性の付与といった痕跡隠しも記録されています。4段目は、curlの出力をそのままシェルへ渡す形で外部のスクリプトを実行し、収集結果をKestra自身のキーバリュー機能に格納するというものです。

最後の点は、調査の視点として押さえておく価値があります。収集した情報を独立したファイルとして置かず、アプリケーション自身のデータストアへ入れているため、ディスク上のファイルを探す方式の調査では見つかりません。KVストアの中身を確認対象に含める必要があります。

Microsoft Security Blogの2026年8月26日の記事は、LiteLLMゲートウェイ、RAGFlow、Kestraの3つの環境で観測した侵害を扱っています。Kestraについては「Microsoft assesses with high confidence that initial access likely occurred through exploitation of CVE-2026-49869」と記載し、観測活動としてworkflow-origin shell execution、Docker and container-environment discovery、XMRig deployment、follow-on data collectionを挙げています。防御側への示唆として、ゲートウェイや検索基盤やオーケストレーション基盤は資格情報とデータ参照と実行権限が1つのランタイムに集まるため、アプリケーション起点のシェルや対話型インタプリタの起動を、シークレットへのアクセス、Dockerソケットの利用、外部へのコールバック、資源の乗っ取りといった事象と相関させて検知すべきだと述べています。

ログと痕跡をどこで見るか

Kestraは実行の履歴とログを自身のデータストアに持ちます。確認する順序としては、まずアプリケーション側の記録を見て、次にホストとコンテナ側の記録を見ます。

アプリケーション側では、フローの一覧に運用者が定義した覚えのないものがないかを確認します。次に実行履歴を時系列で追い、通常のスケジュールやトリガに紐づかない実行がないかを見ます。KVストアは、キーの一覧を出して身に覚えのないものがないかを確認します。

ここで一つ注意が要ります。アドバイザリは、認証を迂回できる操作の中にログの削除が含まれることを明記しています。攻撃後にログが消されていれば、記録が残っていないこと自体が正常を意味しません。特定の名前空間だけログが不自然に欠けている状態は、それ自体が確認すべき兆候です。

ホストとコンテナ側では、ワーカーのプロセスの親子関係を見ます。ワーカーのプロセスから直接シェルや対話型インタプリタが起動している系列は、正規のスクリプトタスクでも発生しうるため、実行履歴のどのタスクに対応するかを突き合わせて判断します。対応する実行が見つからないシェル起動が残っていれば、優先して調べる対象です。

ネットワーク側では、ワーカーが動くホストからの外向き通信を確認します。マイニングプールで使われる宛先、生のIPアドレスへの直接接続、通常使わないポートへの接続が手がかりになります。前段でFQDNによる絞り込みを行っている環境であれば、拒否ログのほうに痕跡が残っていることがあります。

# ワーカーホストでの確認例。実行中プロセスの親子関係
ps -eo pid,ppid,user,etime,cmd --forest | grep -A5 -i kestra

# 一時ディレクトリ配下の実行可能ファイル
find /tmp /var/tmp -maxdepth 2 -type f -perm -u+x -newermt '-90 days' -ls

# 不変属性が付けられたファイル
lsattr -R /tmp 2>/dev/null | grep -E '^....i'

# 外向き通信の確認
ss -tnp state established

痕跡が見つからないことは、侵害されていない証明にはなりません。ログの保持期間が露出していた期間より短ければ、記録は残っていません。判断の根拠として使えるのは、確認した範囲と期間を明示したうえでの評価です。

認可判定の設計と基盤の資産管理へ戻す

修正コミットが何をしたかを見ると、この種の欠陥の直し方が分かります。

// 修正後(コミット 2475839)の AuthenticationFilter.java より抜粋
String normalizedPath = normalizePath(request.getPath());
boolean isConfigEndpoint = "/api/v1/configs".equals(normalizedPath)
    || ((normalizedPath.matches("/api/v1(/[^/]+)?/basicAuth") || "/api/v1/basicAuthValidationErrors".equals(normalizedPath))
        && !basicAuthService.isBasicAuthInitialized());

private static String normalizePath(String path) {
    return path.replaceAll("/+", "/");
}

変更点は2つです。1つは末尾一致を完全一致に変えたこと、もう1つは連続するスラッシュをまとめる正規化を照合の前に挟んだことです。後者があるのは、完全一致に変えただけでは //api/v1/configs のような表記で照合をすり抜ける余地が残るためです。パス文字列で判定するなら、正規化してから完全一致で照合するという形になります。

設計として押さえるべき点は3つあります。

1つ目は、認証や認可の対象外にするエンドポイントを、パスの部分一致で決めないことです。末尾一致も部分一致も、パスの一部を攻撃者が選べる設計と組み合わさると壊れます。使うなら完全一致か、正規化したうえでの前方一致です。Kestraの open-urls 設定が前方一致であることも、この文脈で見直す対象になります。

2つ目は、管理系と実行系のエンドポイントをインターネットへ晒さないことです。今回の脆弱性はネットワーク到達性さえあれば成立しますが、公開されているかどうかは是正の緊急度を大きく変えます。BOD 26-04の期限が公開状況で変わるのも同じ理由です。ワークフロー基盤、CI/CDの実行基盤、AIゲートウェイのように、設計上コードを実行する製品ほど、到達できる範囲を絞る価値が高くなります。

3つ目は、こうした基盤を資産管理の対象に載せることです。Kestraのようなオープンソースの実行基盤は、開発チームが検証のために立てたものがそのまま運用に入ることがあります。調達を通らないため資産台帳に載らず、脆弱性情報の配信先にも入りません。KEVに載った日に自組織のどこで動いているかを即答できるかどうかが、3日という期限に間に合うかどうかを分けます。

外部に面した機器やサービスの脆弱性をどう扱うかという整理は、次の記事で扱っています。

あわせて読みたい

境界に置くエッジ機器の脆弱性が侵入口として狙われる理由

対応チェックリスト

CVE-2026-49869への対応と確認

  • 本番で稼働しているKestraのバージョンを、GET /api/v1/configs の応答またはコンテナのイメージタグで確認した
  • 1.0系なら1.0.45以上、1.3系なら1.3.21以上であることを確認した。1.1系または1.2系を使っている場合は、その系列に修正版が無いことを前提に移行計画を立てた
  • エンタープライズ版ではなくKestra OSSを使っている構成をすべて洗い出した(この脆弱性はOSSのAuthenticationFilterに固有です)
  • インターネットからの到達可否を、セキュリティグループ、ファイアウォール、ロードバランサ、Ingressの各層で確認した
  • 社内ネットワークからの到達経路についても、ネットワーク的に届く相手なら成立する前提で範囲を確認した
  • kestra.server.basic-auth.open-urls に広すぎる接頭辞を指定していないことを確認した
  • ワーカーのコンテナに /var/run/docker.sock がマウントされていないか、root で動作していないかを確認した
  • フローの一覧、実行履歴、KVストアに、運用者が定義した覚えのない項目が無いことを確認した
  • 特定の名前空間のログが不自然に欠けていないかを確認した(ログ削除も認証なしで実行できる操作に含まれます)
  • ワーカーが動くホストで、実行履歴と対応しないシェル起動、一時ディレクトリ配下の実行ファイル、外向きの想定外通信を確認した
  • 露出していた期間にワーカーから読めた資格情報(環境変数、シークレット、クラウドの一時認証情報)を洗い出し、入れ替えた
  • 更新の適用後、正規の認証が求められること、既存のフローが期待どおり動くことを、許可された検証環境で確認した

判定を完全一致へ戻すという原則

CVE-2026-49869から取り出せる教訓は2つに絞れます。

1つは、認可の判定にパス文字列の部分一致を使わないことです。endsWith() で書けば1行で済み、テストも通ります。壊れるのは、パスの一部を攻撃者が選べると気づいたときだけです。修正コミットが正規化と完全一致の組み合わせに変えたのは、判定の対象を「攻撃者が形を選べる文字列」から「決め打ちの1つの値」へ移したということです。

もう1つは、コードを実行することが仕事である製品は、認証層が1枚剥がれた瞬間に最悪の結果になるという前提で置き場所を決めることです。ワークフロー基盤、ジョブスケジューラ、CI/CDの実行機、AIゲートウェイはいずれも同じ性質を持ちます。CVSSが10.0になった理由は認証バイパスそのものではなく、その先にスクリプト実行プラグインが既定で用意されていたことでした。

対応としては、1.0.45以上または1.3.21以上へ上げることが最短です。1.1系と1.2系を使っている場合は、その系列に修正が来ないという前提で移行の計画を立ててください。そのうえで、自組織のどこでワークフロー基盤が動いているかを一覧にしておくと、次に同じ種類の脆弱性が出たときの初動が変わります。

出典・参考

この記事をシェア

関連する記事

セキュアコーディング

OSコマンドインジェクションの仕組みと根本対策。シェルに渡さず引数を分離する

OSコマンドインジェクション(CWE-78)が外部入力をシェルコマンドとして解釈させて成立する機構、OWASPのインジェクション分類での位置づけ、そしてシェルを介さず引数を配列で渡す根本対策までを開発者向けに整理します。入力検証が補助にとどまる理由も扱います。