CVE-2026-54763(Traefik)— 剥がしたはずのヘッダが後段に届く理由

リバースプロキシが「認証済みのIDを詐称するヘッダを剥がした」あとで、剥がしたはずのヘッダが後段のアプリケーションに届く。CVE-2026-54763 はそういう脆弱性です。原因はハイフンとアンダースコアの扱いという、知らなければ絶対に気づけない正規化の非対称性でした。一次情報で確認した事実と、自分の環境を確認する手順を整理します。

確認日:2026年8月4日。 本記事の版番号・スコア・仕様は、この日に NVD API・CVE Program の記録・Traefik のアドバイザリとリリース・公式移行ドキュメント・v3.6.22 のソース・nginx 公式ドキュメント・RFC 3875・PHP マニュアルを直接参照して確認したものです。攻撃手順・実証コード・具体的なヘッダ値は扱いません。記載するのは、自分の環境に対して行う確認手順だけです。

要点

CVE IDCVE-2026-54763
対象Traefik(HTTPリバースプロキシ/ロードバランサ)の BasicAuth・DigestAuth・ForwardAuth ミドルウェア
影響を受ける版2.11.51 未満/3.0.0-beta1 以上 3.6.22 未満/3.7.0-ea.1 以上 3.7.6 未満
修正版v2.11.51 / v3.6.22 / v3.7.6
CVSS v3.1(NVD 付与)10.0 CRITICAL(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
CVSS v4.0(CNA 付与)7.8 HIGH(CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N
CWECWE-178(大文字小文字の扱いの不備)/ CWE-290 / CWE-345(いずれも CNA 付与)
NVD の状態Analyzed(公開 2026-07-06/最終更新 2026-07-08)
CISA KEV 収載されていない(2026年8月3日版カタログで確認)

何が起きるのか — ハイフンとアンダースコアの非対称性

公式の説明は次のとおりです(原文)。

Traefik is an HTTP reverse proxy and load balancer. Prior to v2.11.51, v3.6.22, and v3.7.6, Traefik's BasicAuth, DigestAuth, and ForwardAuth middlewares strip canonical-cased spoofed identity headers before writing Traefik's own value, but do not account for underscore-variant header names, which many backends normalize identically to dashed forms.

整理すると、次の3つの事実が重なったところに問題が生まれています。

  1. プロキシは「正規形」でヘッダを剥がしていた。 Traefik は認証済みのIDを自前のヘッダに書き込む前に、クライアントが送りつけてきた同名ヘッダを削除します。ところが Go のヘッダ削除が正規化するのは大文字小文字とハイフンだけで、アンダースコアは区切り文字として扱われません。結果として、ハイフン表記の綴りは消えても、アンダースコア表記の兄弟はそのまま残ります。
  2. 後段はハイフンとアンダースコアを区別しない。 CGI 系のインタフェースでは、ヘッダ名を大文字化し、ハイフンをアンダースコアに置換し、HTTP_ を前置してメタ変数名を作ります。したがって、ハイフン版とアンダースコア版は後段から見ると同じ名前になります。
  3. プロキシが「消したつもり」のものが後段に届く。 残ったアンダースコア版が、Traefik が意図して設定した値と並んで(ForwardAuth の authResponseHeaders の経路では、意図した値の代わりに)後段に到達します。後段のアプリケーションは、それを信頼できるヘッダとして読み取ってしまいます。
この構図が怖い理由: Traefik の実装も後段の実装も、それぞれ単体では仕様どおりに動いています。壊れているのは両者の「同じ名前」の定義がずれているという接合部だけです。ログを見ても、プロキシ側には「剥がした」記録が残り、後段には「受け取った」記録が残るので、両方を突き合わせない限り矛盾に見えません。境界をまたぐ正規化の差は、片側だけを見ていると原理的に気づけない種類の欠陥です。

後段の正規化ルール(一次情報)

ハイフンとアンダースコアが同一視されるのは実装依存の癖ではなく、規格に書かれた変換です。RFC 3875(CGI 1.1)の 4.1.18 節にはこうあります(原文)。

Meta-variables with names beginning with "HTTP_" contain values read from the client request header fields, if the protocol used is HTTP. The HTTP header field name is converted to upper case, has all occurrences of "-" replaced with "_" and has "HTTP_" prepended to give the meta-variable name.

PHP のマニュアルの $_SERVER の項にも、同じ趣旨の記述があります(原文)。

In addition to the elements listed below, PHP will create additional elements with values from request headers. These entries will be named HTTP_ followed by the header name, capitalized and with underscores instead of hyphens.

つまり、ハイフン版のヘッダ名とアンダースコア版のヘッダ名は、この変換を経ると完全に同じキーになります。プロキシ側が片方しか消していなければ、後段は残ったほうを読みます。

なぜ nginx には underscores_in_headers があるのか

この問題は今回初めて見つかったものではなく、リバースプロキシの世界では以前から知られた地雷です。nginx には、まさにこのための設定があります。公式ドキュメント(ngx_http_core_module)の記述は次のとおりです(原文)。

Enables or disables the use of underscores in client request header fields. When the use of underscores is disabled, request header fields whose names contain underscores are marked as invalid and become subject to the ignore_invalid_headers directive.

既定が off であること自体が、この危険性への設計上の回答になっています。ただし、細かいところを正確に読んでください。off のとき nginx が行うのは「単純に削除する」ことではなく「無効なヘッダとして印を付ける」ことで、その後どうなるかは ignore_invalid_headers ディレクティブに委ねられます。「nginx はアンダースコア付きヘッダを既定で捨てる」という説明は、結果としては近いものの、因果の記述としては不正確です。

Traefik 側の修正と、注意が必要な点

修正版は v2.11.51 / v3.6.22 / v3.7.6 です。v3.6.22 のリリースノートには、この CVE が修正対象として明記されています。

アップグレードしただけでは既定の挙動は変わりません。 2026年8月4日に v3.6.22 のソースと公式の移行ドキュメントを確認したところ、追加されたのはエントリポイントのオプション underscoreHeadersStrategy で、取りうる値は次の3つでした。
  • keep既定値。リクエストヘッダをそのまま転送する
  • delete — 名前にアンダースコアを含むリクエストヘッダを黙って削除する
  • reject — リクエストを 400 Bad Request で拒否する
既定が keep(従来どおり)である以上、アンダースコアとハイフンを同一視する後段を持つエントリポイントでは、明示的に delete または reject を設定する必要があります。公式ドキュメントの Security の注記も、そうした構成で既定の keep のままにすることは推奨しないとしています。
アドバイザリ本文の記述との食い違い(2026年8月4日確認): GitHub 上のアドバイザリの Summary には、別のオプション名を false に設定することで修正される、という趣旨の記述があります。しかし、v3.6.22 のソース(pkg/config/static/entrypoints.go)と公式の移行ドキュメントで実際に確認できるオプション名は underscoreHeadersStrategy です。設定を書く際は、アドバイザリ本文の文言ではなく公式ドキュメントと実際のソースの名前に合わせてください。

スコアが2つあることについて

この CVE には性格の異なるスコアが2つ付いています。どちらか一方だけを引用すると印象が大きく変わるため、出典とともに扱うのが正確です。

付与元スコアベクタ
NVD(nvd@nist.gov・Primary)CVSS 3.110.0 CRITICALAV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
CNA(GitHub・Secondary)CVSS 4.07.8 HIGHAV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N

10.0 になっているのは、CVSS 3.1 のベクタで Scope が ChangedS:C)と評価されているためです。プロキシという境界を越えて後段の判断を狂わせる、という性質がそのまま反映されています。

引用時の注意: アドバイザリのページには、報告者が提出した原文(Original Description)の中に別の数値の提案が含まれています。それは報告者の提案であって、付与された公式スコアではありません。公式に付与されているのは上の表の2つだけです。自動要約ツールを通すと、この提案値をスコアとして拾ってしまうことがあります。

また、CISA Coordinator による SSVC の判定(2026年7月8日)は exploitation: noneautomatable: yestechnicalImpact: partial でした。2026年8月3日版の CISA KEV カタログを検索した限り、この CVE は収載されていません。

自分の環境を確認する手順

いずれも自分が管理する環境に対して行う確認です。

  1. Traefik の版を確認する。 実行中のバイナリまたはコンテナイメージのタグを見ます。
    # バイナリ
    traefik version
    
    # コンテナ(イメージのタグと、コンテナ内での版の両方を見る)
    docker ps --format '{{.Image}}'
    docker exec <container> traefik version
    イメージタグと実際の版が食い違うことがあるので、タグではなく実行中の版で判断してください。
  2. 該当ミドルウェアを使っているかを確認する。 動的設定の中に basicAuth / digestAuth / forwardAuth があるか、そしてそれらが認証済みのIDを後段へ渡す設定(ヘッダ名を指定するオプションや、ForwardAuth の authResponseHeaders)になっているかを見ます。IDを後段へ渡していなければ、この経路の露出はありません。
  3. 後段がハイフンとアンダースコアを同一視するかを確認する。 PHP・CGI・FastCGI を経由する構成は、上の RFC 3875 の変換規則により該当します。アプリケーションフレームワークによっては独自の正規化を行うため、実際にどうなるかは後段の実装で確認してください。
  4. エントリポイントの設定を確認する。 修正版へ上げたあと、該当するエントリポイントに underscoreHeadersStrategy を明示的に設定したかを確認します。設定していなければ keep(従来どおり)のままです。
  5. 前段に nginx がある場合は既定値を確認する。 underscores_in_headers を明示的に on にしていないか。過去に「アンダースコア付きの独自ヘッダが後段に届かない」という理由で on にした設定が残っていることがあります。

設計上の一般化 — 「正規化のずれ」を疑う場所

今回の欠陥は Traefik 固有の実装ミスというより、境界をまたぐたびに正規化の定義が変わるという構造的な問題です。同じ形の落とし穴は、次のような場所に潜みます。

共通する対策の型はひとつです。剥がす側は「拒否リスト」ではなく「許可リスト」で考える。「危ないヘッダを消す」ではなく「後段へ渡してよいヘッダだけを通す」設計にすれば、綴りのバリエーションを数え漏らしても破綻しません。今回 Traefik に追加された reject という選択肢は、その発想に近い挙動です。

本記事の出典と確認日

攻撃手順・実証コード・具体的なヘッダ値は扱っていません。確認できなかった事項は記載していません。

よくある質問(FAQ)

CVE-2026-54763 の修正版はどれですか?

Traefik の v2.11.51、v3.6.22、v3.7.6 です。影響を受けるのは 2.11.51 未満、3.0.0-beta1 以上 3.6.22 未満、3.7.0-ea.1 以上 3.7.6 未満の各版です(2026年8月4日確認)。

修正版にアップグレードすれば、それだけで対応は完了しますか?

エントリポイントの設定も必要です。修正で追加されたオプション underscoreHeadersStrategy の既定値は keep(従来どおり転送する)であるため、アンダースコアとハイフンを同一視する後段を持つエントリポイントでは、明示的に delete または reject を設定してください(2026年8月4日にソースと公式移行ドキュメントで確認)。

なぜアンダースコア表記のヘッダが問題になるのですか?

CGI のインタフェースでは、ヘッダ名を大文字化し、ハイフンをアンダースコアに置換し、HTTP_ を前置してメタ変数名を作ります(RFC 3875 4.1.18節)。このためハイフン版とアンダースコア版は後段から見ると同じ名前になります。プロキシがハイフン版しか削除していないと、アンダースコア版が生き残って後段に届きます。

この CVE の CVSS はいくつですか?

付与元によって2つあります。NVD が付与した CVSS 3.1 は 10.0 CRITICAL、CNA(GitHub)が付与した CVSS 4.0 は 7.8 HIGH です。なおアドバイザリのページには報告者が提案した別の数値も含まれますが、それは公式に付与されたスコアではありません。

← 技術ブログ一覧へ戻る