19
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

HTTP リクエストの Host ヘッダフィールドを知ろう

Posted at

この記事はRFC7230をもとにしています。つまみ食い読みをしているので、間違っていたらすみません。編集リクエストをいただけると幸いです。


HTTP では、クライアントサーバーモデルに基づき、クライアントがサーバーへリソースを要求(リクエスト)し、サーバーはそれに応答(レスポンス)を返します。

クライアントやサーバーが発するものはメッセージと呼ばれます。メッセージは

  • 0個以上のヘッダフィールド、
  • ヘッダフィールドの終わりを示す空の行、
  • オプション(あってもなくてもよい)としてメッセージボディ

からなります。

この記事では HTTP リクエストの特に Host ヘッダフィールドについて理解することを目的とします。

HTTP リクエストメッセージとレスポンスメッセージは、以下のようなものです。(RFC7230 §2.1から引用)

   Client request:

     GET /hello.txt HTTP/1.1
     User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
     Host: www.example.com // ←ここが Hostヘッダフィールド
     Accept-Language: en, mi


   Server response:

     HTTP/1.1 200 OK
     Date: Mon, 27 Jul 2009 12:28:53 GMT
     Server: Apache
     Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
     ETag: "34aa387-d-1568eb00"
     Accept-Ranges: bytes
     Content-Length: 51
     Vary: Accept-Encoding
     Content-Type: text/plain

     Hello World! My payload includes a trailing CRLF.

HTTP リクエストの Host ヘッダフィールドは、アクセスしたい URI とポートの情報をもちます。

Host: www.example.com
もしくは
Host: www.example.com:80

サーバーは単一の IP アドレスについて複数のホストネームを持つことができます。どのホストネームでリソースを要求されたかによって、提供するリソースを振り分ける必要があります。HTTP リクエストを受け取ったサーバーは Host ヘッダを見ることによって、提供すべきリソースを決めることができます。

HTTP リクエストメッセージは必ず Host ヘッダフィールドを含む必要があります (MUST)。

上の例のリクエストメッセージの1行目

GET /hello.txt HTTP/1.1

のことをリクエストラインと呼びます。リクエストラインの GET の直後、この例では /hello.txt の部分をリクエストターゲット と言います。リクエストターゲットはターゲットの URI から作られ、その書き方は4種類あります。

Authority コンポーネント (johndoe@www.example.com みたいなもの、ユーザー名と @ はなくてもいいので通常は www.example.com の部分) がターゲット URI に含まれる場合は、 Host ヘッダフィールドにも同じ値 (www.example.com) をもつ必要があります (MUST)。

逆にターゲット URI に authority コンポーネントが欠けている場合は、 Host ヘッダフィールドの値は空でなければなりません (MUST)。1

Host ヘッダフィールドの値はリクエストを扱うのに重要な情報ですから、ユーザーエージェント(ブラウザとか)はリクエストラインのすぐ直後に Host ヘッダを生成すべきです (SHOULD)。例えば http://www.example.org/pub/WWW/ へのリクエストは

     GET /pub/WWW/ HTTP/1.1
     Host: www.example.org

というようになります。

HTTP/1.1 リクエストでは、クライアントはリクエストターゲットを absolute-form (リクエストターゲット参照) で書いた場合であっても Host ヘッダを送らなければなりません (MUST)。Host を実装していない可能性がある古代の HTTP/1.0 プロキシはを経由しても Host 情報が渡されるようにするためです。

プロキシが absolute-form のリクエストターゲットを受け取ったとき、プロキシは Host ヘッダフィールドを無視しリクエストターゲットのホスト情報で置き換えなければなりません (MUST)。そのようなリクエストを転送するプロキシも同様です。

Host ヘッダフィールドはアプリケーションレベルでのルーティング機構として振る舞うため、共有キャッシュポイズニングや意図しないサーバーへのリダイレクトを狙うマルウェアの標的となりがちです。透過プロキシがリクエストを内部サーバーに Host フィールドの値に基づいて振り分けていたり、共有キャッシュのキャッシュキーとして用いられていたりしていて、プロキシを通る通信がそのホストにとって有効な IP をターゲットとしているかの検証をしていない場合には、特に脆弱です。

Host ヘッダフィールドがない、または複数ある、または無効な値になっている HTTP/1.1 リクエストに対してサーバーは 400 Bad Request を返さなければなりません (MUST)。

  1. Host ヘッダフィールドが空、すなわち authority コンポーネントがない状況というのはおそらく何らかの異常が起きた状況だと思うのですが、具体的にはどのような状況なのでしょうか。ご存知の方がいらっしゃいましたらコメント欄等で教えていただけると幸いです。

19
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?