リバースプロキシが「認証済みのIDを詐称するヘッダを剥がした」あとで、剥がしたはずのヘッダが後段のアプリケーションに届く。CVE-2026-54763 はそういう脆弱性です。原因はハイフンとアンダースコアの扱いという、知らなければ絶対に気づけない正規化の非対称性でした。一次情報で確認した事実と、自分の環境を確認する手順を整理します。
要点
| CVE ID | CVE-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) |
| CWE | CWE-178(大文字小文字の扱いの不備)/ CWE-290 / CWE-345(いずれも CNA 付与) |
| NVD の状態 | Analyzed(公開 2026-07-06/最終更新 2026-07-08) |
| CISA KEV 収載 | されていない(2026年8月3日版カタログで確認) |
何が起きるのか — ハイフンとアンダースコアの非対称性
公式の説明は次のとおりです(原文)。
整理すると、次の3つの事実が重なったところに問題が生まれています。
- プロキシは「正規形」でヘッダを剥がしていた。 Traefik は認証済みのIDを自前のヘッダに書き込む前に、クライアントが送りつけてきた同名ヘッダを削除します。ところが Go のヘッダ削除が正規化するのは大文字小文字とハイフンだけで、アンダースコアは区切り文字として扱われません。結果として、ハイフン表記の綴りは消えても、アンダースコア表記の兄弟はそのまま残ります。
- 後段はハイフンとアンダースコアを区別しない。 CGI 系のインタフェースでは、ヘッダ名を大文字化し、ハイフンをアンダースコアに置換し、
HTTP_を前置してメタ変数名を作ります。したがって、ハイフン版とアンダースコア版は後段から見ると同じ名前になります。 - プロキシが「消したつもり」のものが後段に届く。 残ったアンダースコア版が、Traefik が意図して設定した値と並んで(ForwardAuth の
authResponseHeadersの経路では、意図した値の代わりに)後段に到達します。後段のアプリケーションは、それを信頼できるヘッダとして読み取ってしまいます。
後段の正規化ルール(一次情報)
ハイフンとアンダースコアが同一視されるのは実装依存の癖ではなく、規格に書かれた変換です。RFC 3875(CGI 1.1)の 4.1.18 節にはこうあります(原文)。
PHP のマニュアルの $_SERVER の項にも、同じ趣旨の記述があります(原文)。
つまり、ハイフン版のヘッダ名とアンダースコア版のヘッダ名は、この変換を経ると完全に同じキーになります。プロキシ側が片方しか消していなければ、後段は残ったほうを読みます。
なぜ nginx には underscores_in_headers があるのか
この問題は今回初めて見つかったものではなく、リバースプロキシの世界では以前から知られた地雷です。nginx には、まさにこのための設定があります。公式ドキュメント(ngx_http_core_module)の記述は次のとおりです(原文)。
- 構文:
underscores_in_headers on | off; - 既定値:
underscores_in_headers off; - コンテキスト:
http,server
既定が off であること自体が、この危険性への設計上の回答になっています。ただし、細かいところを正確に読んでください。off のとき nginx が行うのは「単純に削除する」ことではなく「無効なヘッダとして印を付ける」ことで、その後どうなるかは ignore_invalid_headers ディレクティブに委ねられます。「nginx はアンダースコア付きヘッダを既定で捨てる」という説明は、結果としては近いものの、因果の記述としては不正確です。
Traefik 側の修正と、注意が必要な点
修正版は v2.11.51 / v3.6.22 / v3.7.6 です。v3.6.22 のリリースノートには、この CVE が修正対象として明記されています。
underscoreHeadersStrategy で、取りうる値は次の3つでした。
keep— 既定値。リクエストヘッダをそのまま転送するdelete— 名前にアンダースコアを含むリクエストヘッダを黙って削除するreject— リクエストを 400 Bad Request で拒否する
keep(従来どおり)である以上、アンダースコアとハイフンを同一視する後段を持つエントリポイントでは、明示的に delete または reject を設定する必要があります。公式ドキュメントの Security の注記も、そうした構成で既定の keep のままにすることは推奨しないとしています。
false に設定することで修正される、という趣旨の記述があります。しかし、v3.6.22 のソース(pkg/config/static/entrypoints.go)と公式の移行ドキュメントで実際に確認できるオプション名は underscoreHeadersStrategy です。設定を書く際は、アドバイザリ本文の文言ではなく公式ドキュメントと実際のソースの名前に合わせてください。
スコアが2つあることについて
この CVE には性格の異なるスコアが2つ付いています。どちらか一方だけを引用すると印象が大きく変わるため、出典とともに扱うのが正確です。
| 付与元 | 版 | スコア | ベクタ |
|---|---|---|---|
| NVD(nvd@nist.gov・Primary) | CVSS 3.1 | 10.0 CRITICAL | AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N |
| CNA(GitHub・Secondary) | CVSS 4.0 | 7.8 HIGH | AV: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 が Changed(S:C)と評価されているためです。プロキシという境界を越えて後段の判断を狂わせる、という性質がそのまま反映されています。
また、CISA Coordinator による SSVC の判定(2026年7月8日)は exploitation: none/automatable: yes/technicalImpact: partial でした。2026年8月3日版の CISA KEV カタログを検索した限り、この CVE は収載されていません。
自分の環境を確認する手順
いずれも自分が管理する環境に対して行う確認です。
- Traefik の版を確認する。 実行中のバイナリまたはコンテナイメージのタグを見ます。
# バイナリ traefik version # コンテナ(イメージのタグと、コンテナ内での版の両方を見る) docker ps --format '{{.Image}}' docker exec <container> traefik version
イメージタグと実際の版が食い違うことがあるので、タグではなく実行中の版で判断してください。 - 該当ミドルウェアを使っているかを確認する。 動的設定の中に
basicAuth/digestAuth/forwardAuthがあるか、そしてそれらが認証済みのIDを後段へ渡す設定(ヘッダ名を指定するオプションや、ForwardAuth のauthResponseHeaders)になっているかを見ます。IDを後段へ渡していなければ、この経路の露出はありません。 - 後段がハイフンとアンダースコアを同一視するかを確認する。 PHP・CGI・FastCGI を経由する構成は、上の RFC 3875 の変換規則により該当します。アプリケーションフレームワークによっては独自の正規化を行うため、実際にどうなるかは後段の実装で確認してください。
- エントリポイントの設定を確認する。 修正版へ上げたあと、該当するエントリポイントに
underscoreHeadersStrategyを明示的に設定したかを確認します。設定していなければkeep(従来どおり)のままです。 - 前段に nginx がある場合は既定値を確認する。
underscores_in_headersを明示的にonにしていないか。過去に「アンダースコア付きの独自ヘッダが後段に届かない」という理由でonにした設定が残っていることがあります。
設計上の一般化 — 「正規化のずれ」を疑う場所
今回の欠陥は Traefik 固有の実装ミスというより、境界をまたぐたびに正規化の定義が変わるという構造的な問題です。同じ形の落とし穴は、次のような場所に潜みます。
- 大文字小文字。 HTTPヘッダ名は本来大文字小文字を区別しませんが、それを自前で扱うコードでは区別してしまいがちです(今回の CWE-178 がまさにこれです)。
- 区切り文字の等価性。 ハイフンとアンダースコア、スペースとプラス、スラッシュの重複など。
- Unicode 正規化。 見た目が同じで符号位置が異なる文字。比較の前に正規化しているか。
- パーセントエンコーディングの復号回数。 どの層で何回デコードするか。
- 末尾のスラッシュ・大文字小文字を含むパス比較。 アクセス制御をパス文字列で行っている場合。
共通する対策の型はひとつです。剥がす側は「拒否リスト」ではなく「許可リスト」で考える。「危ないヘッダを消す」ではなく「後段へ渡してよいヘッダだけを通す」設計にすれば、綴りのバリエーションを数え漏らしても破綻しません。今回 Traefik に追加された reject という選択肢は、その発想に近い挙動です。
本記事の出典と確認日
- 確認日:2026年8月4日
- NVD API(CVSS・CWE・CPE・状態・日付): https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-54763
- CVE Program の記録(説明文・影響範囲・CNA付与スコア): https://cveawg.mitre.org/api/cve/CVE-2026-54763
- Traefik のアドバイザリ: https://github.com/traefik/traefik/security/advisories/GHSA-x677-9fxg-v5c5
- Traefik v3 移行ドキュメント(
underscoreHeadersStrategyの値と既定): https://doc.traefik.io/traefik/v3.6/migrate/v3/、および v3.6.22 のソースpkg/config/static/entrypoints.go - nginx 公式ドキュメント(
underscores_in_headers): https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers - RFC 3875 4.1.18 節(CGI のメタ変数名の作り方): https://www.rfc-editor.org/rfc/rfc3875.txt
- PHP マニュアル
$_SERVER: https://www.php.net/manual/en/reserved.variables.server.php - CISA Known Exploited Vulnerabilities カタログ(版 2026.08.03、1,657件・収載なしを確認): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
攻撃手順・実証コード・具体的なヘッダ値は扱っていません。確認できなかった事項は記載していません。
よくある質問(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 です。なおアドバイザリのページには報告者が提案した別の数値も含まれますが、それは公式に付与されたスコアではありません。