net/http: add Server.MaxHeaderValueCount \\[freeze exception]
要約
概要
net/http.Server にリクエストヘッダーの個数上限を指定できる新フィールド MaxHeaderValueCount と定数 DefaultMaxHeaderValueCount = 500 を追加するプロポーザル。HTTP/2ヘッダーを利用したDoS攻撃(いわゆる「HTTP/2 Bomb」)への対策として、フリーズ例外としてGo 1.27への早期投入が承認された。
ステータス変更
likely_accept → accepted
2026年6月24日に開催されたProposal Review Meeting(@aclements、@neild、@griesemer、@ianlancetaylor 他)において、前回のlikely accept時から合意に変化なしとして正式にacceptedとなった。フリーズ例外も別途承認済みで、Go 1.27への実装が確定している。
技術的背景
現状の問題点
net/http.Server が提供するヘッダー制限手段は MaxHeaderBytes(ヘッダーの総バイト数上限)のみ。しかしこれは、送信側のワイヤ上のバイト数ではなく、サーバー内部表現のバイト数を基準とする。
2026年に注目を集めた「HTTP/2 Bomb」攻撃(Codex発見の手法)では、1バイトの名前・0バイトの値を持つ大量の小さなヘッダーをHPACK圧縮で送りつけることで、サーバーが内部的に確保するメモリ(1エントリあたり32〜4000バイト超の管理領域)を爆発的に消費させる。
MaxHeaderBytes を小さく設定すればDoSリスクは下がるが、SSOクッキーなど大きな正当なヘッダーが壊れる可能性がある。この「大きなヘッダーを許容しつつ、ヘッダー個数は制限する」という操作が現在はできない。
提案された解決策
package http
// DefaultMaxHeaderValueCount はHTTPリクエストで許容するヘッダー値の最大個数。
const DefaultMaxHeaderValueCount = 500
type Server struct {
// MaxHeaderValueCount はサーバーがパースするリクエストヘッダー値の最大個数を制御する。
// ゼロの場合は DefaultMaxHeaderValueCount が使われる。
MaxHeaderValueCount int
}
ヘッダーの個数を直接制限することで、「1バイトのヘッダーを大量送信して内部の管理領域を枯渇させる」という攻撃を防ぐ。
これによって何ができるようになるか
ヘッダーの「サイズ」と「個数」を独立して制御できるようになる。
コード例
// Before: 個数を制限する手段がなく、大きなヘッダーを許可するには
// MaxHeaderBytes を増やすしかなく、DoSリスクが上がる
server := &http.Server{
MaxHeaderBytes: 1 << 20, // 1MB (SSOクッキーに対応するため増やしているが危険)
}
// After: 個数とサイズを独立して制御できる
server := &http.Server{
MaxHeaderBytes: 1 << 20, // 1MB (大きなSSOクッキーを許可)
MaxHeaderValueCount: 100, // ヘッダー個数は100個に制限してDoSを防ぐ
}
議論のハイライト
- GoチームはGoのHTTP/2実装が直接の攻撃対象外であることを確認しつつも、ユーザーが独自に防御手段を持てないことを問題視。各ヘッダーに32バイトのオーバーヘッドを計上しているため既存実装は安全だが、それを前提とした防御オプションが欠如していた。
- 当初はGODEBUG経由の回避策(
GODEBUG=httpmaxheadervalues=N、Issue #80020)も提案されたが、proposal committeeはフリーズ例外でGo 1.27への直接追加を優先し、GODEBUGを省略する方向でまとまった。 - @aclements が「
MaxHeaderBytesで増やせば1つの大きなヘッダーを送られるだけでは?」と指摘。提案者(@nicholashusin)は「それは対称的な攻撃であり増幅がないためDoSは難しい。小ヘッダー多量送信のほうが攻撃者にとって有利」と応答し、CPU負荷(正規化・GC)面でも個数制限に意義があることを説明した。 - トレーラーヘッダーへの適用範囲は未定義のまま承認。HTTP/1はトレーラーに
MaxHeaderBytesを適用しない実装になっており、当面は既存のMaxHeaderBytesの挙動に準じる予定。長期的にはトレーラーにも適用する方向が望ましいとされている。 - 実装CL(go.dev/cl/792620)は
Server.MaxHeaderCountという名前も含む形で提出されており、GODEBUGとの統合も実装に含まれている可能性がある。