独自記事
CVE-2026-65602
TraefikのKubernetes CRD Providerに存在したCVE-2026-65602の認可バイパスについて、影響、成立条件、修正内容を解説します。
Traefikの認可バイパス脆弱性「CVE-2026-65602」を解説
2026年7月9日、TraefikのKubernetes CRD Providerに存在した認可不備が、GitHub Security Advisoryで公開されました。
この脆弱性には CVE-2026-65602 が割り当てられており、GitHub上では GHSA-42cj-m3vj-89wv として管理されています。AdvisoryのCreditsには、CuB3y0nd氏とGitHubアカウント james-yusuke がReporterとして記載されています。
この記事では、公開されたアドバイザリと修正差分をもとに、脆弱性の仕組み、影響、成立条件、修正内容、利用者が確認すべきポイントを日本語で整理します。
本記事は、修正版の公開後に公表された情報を解説するものです。第三者が管理する環境では、許可を得ずに検証しないでください。
脆弱性の概要
| 項目 | 内容 |
|---|---|
| CVE ID | CVE-2026-65602 |
| GitHub Advisory | GHSA-42cj-m3vj-89wv |
| 対象 | Traefik Kubernetes CRD Provider |
| 脆弱性の種類 | 不適切な認可処理(CWE-863) |
| 深刻度 | Moderate |
| CVSS v4.0 | 5.3 |
| 影響を受ける機能 | IngressRouteTCP の serversTransport |
| 修正版 | v3.6.23、v3.7.7 |
| 公開日 | 2026年7月9日 |
| 報告者 | CuB3y0nd、james-yusuke |
一言で表すと、次のような問題です。
本来はクロスプロバイダー参照を許可されていないKubernetes名前空間から、
IngressRouteTCPを通じて、File Providerなどに定義された特権的なTCPServersTransportを参照できてしまう。
これにより、低権限のKubernetesユーザーが、Traefikに対して、運用者が用意したmTLSクライアント証明書やSPIFFEアイデンティティなどを使ってバックエンドへ接続させられる可能性がありました。
前提となるTraefikの仕組み
Providerとクロスプロバイダー参照
Traefikは、Kubernetes CRD、File、Dockerなど、複数のProviderから動的設定を取得できます。
別のProviderに存在する設定を参照する場合、Traefikでは一般に次の形式を使用します。
設定名@Provider名
例えば、次の指定は、File Providerに定義されたprivileged-mtlsという設定を参照することを意味します。
privileged-mtls@file
このように、あるProviderの設定から別のProviderのリソースを参照することを、クロスプロバイダー参照と呼びます。
crossProviderNamespacesとは
Kubernetes環境では、複数のチームや利用者が同じTraefikを共有する場合があります。そのためTraefikには、どのKubernetes名前空間からクロスプロバイダー参照を宣言してよいかを制限する、crossProviderNamespacesという許可リストがあります。
設定の意味は次のとおりです。
| 設定値 | 動作 |
|---|---|
| 未設定 | すべての名前空間からクロスプロバイダー参照を許可 |
[] |
すべての名前空間からのクロスプロバイダー参照を拒否 |
["operator-only"] |
operator-only名前空間からのみ許可 |
例えば、運用者専用の名前空間だけを許可する場合は、概念的には次のようになります。
providers:
kubernetesCRD:
crossProviderNamespaces:
- operator-only
この設定がある場合、defaultやtenant-aなど、一覧に含まれていない名前空間からのfoo@fileといった参照は、本来拒否されなければなりません。
なお、crossProviderNamespacesとallowCrossNamespaceは別の設定です。
allowCrossNamespaceは、Kubernetes CRD同士で別名前空間のリソースを参照できるかを制御します。crossProviderNamespacesは、Kubernetesリソースから@fileなどの別Providerを参照できる名前空間を制御します。
今回問題になったのは後者です。
TCPServersTransportとは
TCPServersTransportは、TraefikからTCPバックエンドへ接続するときの通信方法を定義する設定です。
代表的には、次のような内容を保持できます。
- バックエンドへの接続タイムアウト
- TLSのServer Name
- mTLSで使用するクライアント証明書
- 信頼するルートCA
- SPIFFE関連設定
- PROXY Protocolのバージョン
つまり、TCPServersTransportは単なるタイムアウト設定ではありません。場合によっては、Traefikがバックエンドへ提示する認証上のアイデンティティを保持しています。
何が問題だったのか
IngressRouteTCPでは、TCPサービスに対してserversTransportを指定できます。
説明用に一部だけ示すと、次のような構造です。
services:
- name: backend
port: 443
tls: true
serversTransport: privileged-mtls@file
ここで、このIngressRouteTCPがtenant-a名前空間に存在し、Traefik側の許可リストが次のようになっていたとします。
crossProviderNamespaces:
- operator-only
tenant-aは許可リストに含まれていないため、privileged-mtls@fileの参照は拒否されるべきです。
しかし脆弱なバージョンでは、HTTP用のserversTransportでは許可リストが確認されていた一方、TCP用のserversTransportでは同じ確認が抜けていました。
そのため、許可されていない名前空間から指定されたprivileged-mtls@fileが、そのままTraefikの動的TCPサービス設定へ保存されていました。
攻撃の流れ
flowchart LR
A["低権限のKubernetesユーザー<br/>tenant-a名前空間"] --> B["IngressRouteTCPを作成"]
B --> C["serversTransportに<br/>privileged-mtls@fileを指定"]
C --> D{"crossProviderNamespacesを確認"}
D --> E["脆弱なTCP経路では<br/>認可確認が抜ける"]
E --> F["File Providerの<br/>TCPServersTransportを参照"]
F --> G["TraefikがmTLS証明書や<br/>SPIFFE設定を用いて接続"]
G --> H["保護されたバックエンド"]
重要なのは、設定値が単に保存されるだけではなかった点です。
公開された検証では、指定されたfoo@fileがTCP Dialerによって実際に解決され、そのTransportに設定されたクライアント証明書がmTLSバックエンドへ提示されることまで確認されています。
これは「証明書の窃取」ではない
この脆弱性を説明するときは、影響を正確に表現する必要があります。
攻撃者が、File Provider内の秘密鍵や証明書ファイルをそのまま読み出せるわけではありません。
代わりに発生するのは、次のような状況です。
攻撃者が、Traefikに対して、運用者が用意した特権的な通信アイデンティティを使わせる。
Traefikが本来信頼されているクライアントとしてバックエンドへ接続するため、これはアイデンティティ・リレーや**Confused Deputy(権限を持つ代理人の悪用)**に近い問題です。
バックエンド側の構成や公開されたルートによっては、攻撃者が次のような影響を与える可能性があります。
- mTLSで保護された内部サービスへの接続
- Traefikに付与されたクライアントアイデンティティの不正利用
- バックエンド上の機密情報へのアクセス
- バックエンド上のデータや処理への不正な変更
- SPIFFEアイデンティティを前提とした信頼境界の回避
- 意図しないPROXY Protocol設定の利用
ただし、実際の影響範囲は、Traefikから到達可能なバックエンド、ルーティング設定、NetworkPolicy、Kubernetes RBAC、バックエンドの認可方式などに依存します。
根本原因
根本原因は、HTTP経路とTCP経路における認可処理の不整合です。
脆弱なTCP側の処理は、概念的には次のような動作でした。
if isCrossProviderReference(name) {
return name, nil
}
つまり、@fileなどのProvider名を含む参照を検出すると、呼び出し元の名前空間が許可されているかを確認せず、そのまま返していました。
一方、HTTP側には概念的に次の確認が存在していました。
if isCrossProviderReference(name) {
if !isNamespaceAllowed(parentNamespace) {
return error
}
return name, nil
}
同じセキュリティ方針を適用すべき兄弟機能で、TCP側だけ認可チェックが欠けていたことが原因です。
修正内容
修正Pull Requestでは、Kubernetes CRD ProviderのTCP用Transport参照を生成する処理に、crossProviderNamespacesの確認が追加されました。
修正後は、クロスプロバイダー参照を検出した場合、参照元となるIngressRouteTCPの名前空間が許可リストに含まれているかを確認します。
テストでは、次の4パターンが確認されています。
crossProviderNamespaces |
修正後の動作 |
|---|---|
| 未設定 | 後方互換性のため参照を許可 |
| 空のリスト | 参照を拒否し、対象サービスを生成しない |
| 参照元名前空間を含む | 参照を許可 |
| 参照元名前空間を含まない | 参照を拒否し、対象サービスを生成しない |
この「未設定の場合は許可」という挙動は仕様上の後方互換性です。そのため、マルチテナント環境では、アップデートに加えてcrossProviderNamespacesを明示的に設定することも重要です。
影響を受けるバージョン
GitHub Security Advisoryに記載された影響範囲は次のとおりです。
| 系列 | 影響を受けるバージョン | 修正版 |
|---|---|---|
| Traefik 3.6 | v3.6.0以上、v3.6.22以下 | v3.6.23 |
| Traefik 3.7 | v3.7.0以上、v3.7.6以下 | v3.7.7 |
crossProviderNamespaces自体は、Traefikの移行ドキュメント上、v3.6.17およびv3.7.1で追加されています。そのため実運用上は、同機能による制限を設定し、その制限がTCP経路にも適用されると期待していた環境で問題が顕在化します。
ただし、バージョン判定はベンダーが公開しているSecurity Advisoryの範囲に従い、該当する場合は修正版へ更新してください。
CVSS 5.3となった理由
公式のCVSS v4.0ベクトルは次のとおりです。
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N
主な内容は次のとおりです。
| 指標 | 評価 | 意味 |
|---|---|---|
| Attack Vector | Network | ネットワーク経由で成立 |
| Attack Complexity | Low | 複雑な競合状態などは不要 |
| Attack Requirements | Present | 特定の構成やTransportが必要 |
| Privileges Required | Low | IngressRouteTCPを作成・変更できる低権限が必要 |
| User Interaction | None | 別ユーザーの操作は不要 |
| Vulnerable System Impact | None | Traefik自体への直接的なC・I・A影響は評価されていない |
| Subsequent System Impact | Confidentiality High / Integrity High | 接続先バックエンドへの影響が大きい可能性 |
この評価からも、Traefik本体を直接乗っ取る脆弱性というより、Traefikを信頼された代理人として利用し、後段のシステムへ影響を与える性質であることが分かります。
また、Attack VectorがNetworkであっても、インターネット上の未認証ユーザーが即座に悪用できるという意味ではありません。通常は、Kubernetes上でIngressRouteTCPを作成または更新できる権限が必要です。
成立に必要な主な条件
実際の悪用には、一般に次の条件が関係します。
- 影響を受けるTraefikバージョンを使用している
- Kubernetes CRD Providerが有効になっている
- 攻撃者が
IngressRouteTCPを作成または変更できる - 攻撃者の名前空間が
crossProviderNamespacesに含まれていない - File Providerなどに利用価値のある
TCPServersTransportが存在する - Traefikから対象バックエンドへ到達できる
- 作成したTCPルートを通じて、その接続を利用できる
File Providerに機密性の高いTransportが存在しない場合や、低権限ユーザーがIngressRouteTCPを操作できない場合は、現実的な危険性は下がります。ただし、将来の設定変更で条件がそろう可能性もあるため、該当バージョンは更新すべきです。
推奨される対策
1. 修正版へ更新する
最も確実な対策は、次の修正版へ更新することです。
- Traefik v3.6.23
- Traefik v3.7.7
または、修正を含むそれ以降のメンテナンスリリースを使用してください。
2. IngressRouteTCPのRBACを見直す
信頼できない利用者に対して、クラスタ全体や不要な名前空間でIngressRouteTCPの作成・更新権限を付与していないか確認します。
特に、次の操作権限を持つRoleやClusterRoleを確認してください。
apiGroups: ["traefik.io"]
resources: ["ingressroutetcps"]
verbs: ["create", "update", "patch"]
3. Admission Policyでクロスプロバイダー参照を制限する
すぐに更新できない場合の暫定対策として、Kyverno、OPA Gatekeeper、ValidatingAdmissionPolicyなどを使い、信頼できない名前空間ではserversTransportに@を含む値を指定できないようにする方法があります。
crossProviderNamespacesだけを設定しても、脆弱なバージョンのTCP経路ではその確認自体が抜けているため、アップデートの代わりにはなりません。
4. 機密性の高いTransportを分離する
強いmTLSクライアント証明書やSPIFFEアイデンティティを持つTransportを、複数テナントが共有するTraefikインスタンスに無制限で登録しないことも重要です。
必要に応じて、次のような分離を検討できます。
- 管理系と一般公開系でTraefikを分ける
- テナントごとにIngress Controllerを分ける
- Traefikからバックエンドへの通信をNetworkPolicyやファイアウォールで制限する
- クライアント証明書の権限を最小化する
5. 不審な利用が疑われる場合は認証情報を更新する
不正なIngressRouteTCPが確認された場合は、関連するアクセスログやKubernetes Audit Logを調査し、必要に応じてmTLSクライアント証明書や関連資格情報を失効・更新してください。
環境を確認する方法
Traefikのコンテナイメージを確認する
ラベルを標準的に付けている環境では、次のようなコマンドでTraefikのイメージを確認できます。
kubectl get deployment -A \
-l app.kubernetes.io/name=traefik \
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,IMAGE:.spec.template.spec.containers[*].image'
Helmのリリース名やラベルを変更している場合は、環境に合わせてDeploymentを確認してください。
クロスプロバイダー参照を持つIngressRouteTCPを列挙する
次のコマンドは、serversTransportに@を含むサービスを一覧化します。
kubectl get ingressroutetcps.traefik.io -A -o json |
jq -r '
.items[] as $route
| $route.spec.routes[]?.services[]?
| select(((.serversTransport // "") | contains("@")))
| [
$route.metadata.namespace,
$route.metadata.name,
(.name // "-"),
.serversTransport
]
| @tsv
'
出力された参照が存在するだけで、直ちに攻撃されたことを意味するわけではありません。
次の点を照合してください。
- 参照元名前空間が
crossProviderNamespacesで許可されているか - その
IngressRouteTCPを作成・更新した主体は誰か - 参照先TransportにmTLS証明書やSPIFFE設定があるか
- ルートの接続先が機密性の高いバックエンドか
- 該当ルートへの不審な接続履歴があるか
修正版では、許可されていない名前空間からの参照に対し、namespace is not in crossProviderNamespacesという趣旨のエラーが記録され、対象サービスが生成されません。
この脆弱性から得られる教訓
認可処理は機能ごとに複製しない
HTTPとTCPで似た処理を別々に実装すると、一方だけ修正され、もう一方に認可漏れが残る可能性があります。
可能であれば、クロスプロバイダー参照の解析と認可を共通関数へ集約し、HTTP、TCP、UDPなどすべての経路で同じセキュリティ不変条件を通す設計が望まれます。
参照文字列は「能力」として扱う
foo@fileは単なる名前ではありません。その参照によって、証明書、内部サービス、Transport設定など、別の信頼領域にある機能を利用できる場合があります。
このような参照は、一般的な文字列ではなく、権限を伴うCapabilityとして扱い、参照を解決する直前まで認可を検証する必要があります。
マルチテナントIngress Controllerは強い代理権限を持つ
Ingress Controllerは、外部からの通信を受けるだけでなく、内部バックエンドへ接続する強い権限も持っています。
そのため、テナントが作成できるルーティング設定と、Ingress Controllerが保持する証明書・ネットワーク到達性・サービスアカウント権限を組み合わせて脅威モデルを考える必要があります。
公開情報について
GitHub Security AdvisoryのCredits欄には、次の2名がReporterとして掲載されています。
- CuB3y0nd
- james-yusuke
james-yusukeはこの記事を書いているGitHubアカウントです。ここではCreditsそのものよりも、公開済みのAdvisoryと修正Pull Requestから確認できる影響と対策に焦点を当てます。
まとめ
CVE-2026-65602は、TraefikのKubernetes CRD Providerにおいて、IngressRouteTCPのserversTransportだけcrossProviderNamespacesの認可確認が欠けていた脆弱性です。
許可されていない名前空間の低権限ユーザーが、File Providerなどに定義されたTCPServersTransportを参照し、Traefikに運用者側のmTLS証明書やSPIFFEアイデンティティを使わせられる可能性がありました。
ポイントは次のとおりです。
- HTTP側にはあった認可チェックがTCP側で欠落していた
- 設定が保存されるだけでなく、実際のバックエンド接続に使用された
- 証明書ファイルの直接窃取ではなく、Traefikのアイデンティティを代理利用する問題だった
- 修正版はv3.6.23およびv3.7.7
crossProviderNamespacesの設定だけでは、脆弱なバージョンの代替対策にならない- RBAC、Admission Policy、ネットワーク分離も防御層として重要
マルチテナントなKubernetes環境でTraefikを利用している場合は、バージョンだけでなく、IngressRouteTCPを操作できる主体、クロスプロバイダー参照、File Provider内のTransport、バックエンドへの到達性まで含めて確認することを推奨します。