HTTP_*

メタ変数群 HTTP_* (CGI)

[5] CGIメタ変数HTTP_* は、クライアントから送られてきた要求メッセージ中の頭欄CGIスクリプトに提供するためのものです。

仕様書

名前

[6] HTTP_** の部分は、頭欄名前をすべて大文字にし、 - が含まれていればすべて _ に置き換えたものとなります。 >>7

[20] 例えば、 Accept: 欄に対応するメタ変数名は HTTP_ACCEPT となりますし、 If-Modified-Since: 欄に対応するものは HTTP_IF_MODIFIED_SINCE となります。

[33] _ が元々頭欄名前に含まれている場合どうしたらいいのでしょう・・・。

[13]HTTP_* メタ変数の値には、 クライアントからの HTTP 要求頭欄欄本体がそのまま入れられます。 ただし、次に示すものも含め、意味的に等価な変形を行なって構わないことになっています。 >>7

[24] Accept-LanguageAccept_language のように本来別の頭欄が命名規則のために衝突する場合や、 複数の値を , によって意味的に等価でありつつ連結できない場合 (本来それは HTTP 違反ですが、しばしばあります。) にどうするべきかは規定されていません。 後者については実際には頭欄の種類ごとに処理を分ける意味もないでしょうから、 何も考えずに連結しているものと思われます。

提供されないことが多い頭欄

[14] 鯖はすべての頭欄をこの形のメタ変数として提供する必要はありません。 RFC 3875 4.1.18 特に CONTENT_TYPE (Content-Type) など他にメタ変数が用意されているもの、 Authorization など安全上好ましくないもの、 Connection など通信にのみ関係するものは提供されないかもしれません。

[11] >>9 に規定されているように、鯖は CGI スクリプトに要求メッセージのすべての頭欄を HTTP_* メタ変数を通じて提供する必要はありません。 多くの実装では、次の頭欄は提供されません。

HTTP 頭欄代替メタ変数
AuthorizationAUTH_*
Content-LengthCONTENT_LENGTH
Content-TypeCONTENT_TYPE

[3] >>9 つまり、 CGI 的には HTTP_AUTHORIZATION と かが提供されていて問題がないということです。

[4] >>3 でも Apache は提供してくれません。

[10] CGI メタ変数はほとんどの環境では環境変数として実装されていますが、 環境変数が安全でない環境も少なくありません。 その鯖の任意の利用者が環境変数の値を見ることができるかもしれません。 CGI で昔から認証系の頭欄が提供されないことになっているのはそのような事情があります。

[27] Authorization: の他、 Proxy-Authorization: も安全上注意が必要であり、提供しないことも検討するべきだと指摘されています >>26

[35] サーバーによっては、 HTTP_PROXY 環境変数に関する脆弱性を防ぐため、 Proxy: ヘッダーがあっても HTTP_PROXY メタ変数を省略するようです。

[32] WSGI と派生仕様は HTTP_*HTTP 要求頭欄に対応するべきであるとしており、 CONTENT_TYPECONTENT_LENGTH を除き、 一部の頭欄を引き渡さないことは原則として認められていないようです。 >>28, >>29, >>30, >>31

歴史

[17] HTTP_* メタ変数群を使った要求中の一般の頭欄CGIスクリプトに提供する方法は CGI/1.1 で導入されました。 CGI/1.0 では CONTENT_TYPEHTTP_ACCEPT など一部の頭欄のみが提供されていました。

[NCSA] での説明

[6]

In addition to these, the header lines received from the client, if any, are placed into the environment with the prefix HTTP_ followed by the header name. Any - characters in the header name are changed to _ characters. The server may exclude any headers which it has already processed, such as Authorization, Content-type, and Content-length. If necessary, the server may choose to exclude any or all of these headers if including them would exceed any system environment limits.

これら (訳注: 他の CGI メタ変数群) に加えて、クライアントから受け取った頭行があれば、 これが接頭辞 HTTP_ で始まって頭名が続く環境変数に入れられます。 頭名中の - はすべて _ に変更します。 サーバーは既に処理した頭、 例えば Authorization, Content-type, Content-length は除いても構いません。 必要なら、サーバーはこうした頭の一部又は全部を含めるとシステムの環境制限を越える時には除いても構いません。

RFC 3875 (CGI/1.1)

[7] RFC 3875 4.1.18 節を参照。

セキュリティー

[15] 要求メッセージ頭欄には安全上注意して扱うべき情報が含まれていることもあります。 >>10 のように実装方法によってはメタ変数は安全ではないので、 >>14 の通り危険な情報は提供しないなどの注意をは払う必要があります。

[16] ただし >>15 のような配慮が可能なのは、 注意するべき頭欄の種類をあらかじめが把握している場合だけです。 X-Foo-Private-Information: some-important-thing のような頭欄を使っていると、メタ変数を生成し、 それによって CGI が使われている環境にアクセス可能な第三者に盗み見られる危険性があります。

もちろん、盗み見ることができる権限があるのが信頼できる限定された人だけである場合など、 必ずしも危険であるわけではありません。 このようなシステムの設計者は使用するシステムの技術的・ 運用上の性質によく注意して、 安全性と技術的な実装の簡単さや技術的整合性のバランスが取れるようにしなければなりません。

[9] HTTP_ から始まる名前の環境変数を参照するプログラムライブラリーを利用する際には、 メタ変数環境変数として設定された状態のまま呼び出してしまうことが無いよう、 注意する必要があります。

[8] http_proxy も参照してください。

[34] 環境変数 WWW_HOME の意味で HTTP_HOME が使われることがあります。

関連

HTTP/TLS、HTTP/SSL (HTTPS)

[12] SSLTLS の上で HTTP 通信を行っている場合 (いわゆる HTTPS) であっても、 HTTP であることには変わりありませんので、 TCP 上の HTTP と同じ名前で同じようにメタ変数が提供されます。 (ただし実装によってはより安全を配慮した形になっているかもしれません。) 実装によっては SSLTLS によって得られた情報が別のメタ変数を通じて提供されています。

  • [1] 方式 (scheme) が https: だったら HTTPS_* になるんでしょうか。そんなの見たこと無いなあ。
  • [2] >>1 そんなことはないです。 HTTP over SSL でも HTTP_* になります。

[19] HTTPS であることはメタ変数 HTTPS によって表されます。

SIP_* メタ変数

[18] SIP CGI では SIP 要求メッセージメタ変数 SIP_* として提供されます。

HTTP_* 環境変数

[12]

HTTP_*
Apache をはじめ多くの CGI の実装で、 HTTP_* メタ変数 (>>5) は同名の環境変数として実装されています。
HTTP_HOME
w3m など Webブラウザ類でホーム頁URI を指定する環境変数として使われています。
HTTP_PROXY
w3m など WWW 系プログラムで利用するべきを指定する環境変数として使われています。