Host
使い方
すべての HTTP/1.1 リクエストには Host ヘッダーが含まれます。このヘッダーは、1 つの IP アドレスを持つ単一のサーバーが複数のドメインをホストするバーチャルホスティングを可能にします。Host がなければ、サーバーはクライアントがどのドメインに到達しようとしたのかを判断できません。
値には、要求されたホスト名と、コロンで区切られた任意のポート番号が含まれます。ポートが指定されていない場合は、スキームの既定ポートが適用されます。HTTP ならポート 80、HTTPS ならポート 443 です。
Host ヘッダーのない HTTP/1.1 リクエストを受け取ったサーバーは 400 Bad Request で応答します。リクエストに Host ヘッダーが複数含まれる場合も同じレスポンスになります。曖昧さのためにサーバーが正しいバーチャルホストを選択できないからです。
HTTP/2 と HTTP/3 では、:authority 疑似ヘッダーフィールドが Host を置き換えます。HTTP/2 や HTTP/3 のリクエストを送るクライアントは、ホストの情報を代わりに :authority に入れます。ゲートウェイが HTTP/2 のリクエストを HTTP/1.1 に変換する際には、:authority の値から Host ヘッダーを生成します。
Host ヘッダーは Origin ヘッダーとは異なります。Host はすべてのリクエストについて対象サーバーを識別します。Origin はクロスオリジンのリクエストの発信元を識別するもので、CORS のプリフライトリクエストやフォーム送信といった特定の文脈でのみ現れます。
host
対象サーバーのドメイン名または IP アドレスです。
port
任意の TCP ポート番号です。省略された場合は、リクエストのスキームの既定ポートが想定されます(HTTP は 80、HTTPS は 443)。
Host: <host>:<port>
例
Web サーバーへの標準的な HTTPS リクエストでは、443 が HTTPS の既定なのでポートを省略します。
GET /articles/http-headers HTTP/1.1
Host: example.re
サーバーが標準以外のポートで動作している場合は、ホスト名の後にポート番号を含めます。
GET /api/status HTTP/1.1
Host: api.example.re:8443
IP アドレスへのリクエストでは、そのアドレスを直接含めます。この形式は開発環境や内部サービスでよく見られます。
GET /health HTTP/1.1
Host: 192.168.1.100:3000
セキュリティ
Host ヘッダーインジェクションは、アプリケーションが Host の値を検証せずに URL(パスワードリセットのリンク、正規 URL、リダイレクト)の生成に使う場合に発生します。攻撃者が偽装した Host 値を持つリクエストを送ると、アプリケーションは攻撃者が管理するドメインを指すリンクを生成してしまいます。
Host ヘッダーは想定される値のホワイトリストと照合して検証してください。nginx では server_name を定義し、444 を返す既定のキャッチオール server ブロックを用意します。Django では ALLOWED_HOSTS に許可するドメインのリストを設定します。Rails ではアプリケーションの環境設定で host_authorization を構成します。ブラウザは Host を禁止リクエストヘッダーとして扱うため、クライアントサイドの JavaScript が値を変更することはできませんが、サーバー間のリクエストや curl のようなツールにはそうした制約はありません。