[BUG] Location ヘッダーと組み合わせると CGI で Set-Cookie ヘッダーが無視される

この記事は、以前は次の ID で公開されていました: JP176113
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
マイクロソフトでは、Microsoft Windows Server 2003 で実行される Microsoft インターネット インフォメーション サービス (IIS) 6.0 にアップグレードすることを、すべてのユーザーに強く推奨します。IIS 6.0 により、Web インフラストラクチャのセキュリティが大幅に強化されます。IIS のセキュリティ関連のトピックについては、次のマイクロソフト Web サイトを参照してください。
現象
CGI アプリケーションが "302 Object Moved" 応答および Location ヘッダーと共に Set-Cookie ヘッダーを送信すると、Internet Information Server (IIS) によって Cookie ヘッダーが無視されます。
解決方法
この動作は CGI の仕様に違反しています。CGI の仕様には、「サーバー命令ではないヘッダーはすべて、クライアントに直接送り返されます。現在、この仕様では 3 つのサーバー命令を定義しています...」と記載されています。

回避策としては、EXE ファイルを nph- で始まる名前にして、すべての HTTP ヘッダーを直接プログラム側で作成します。EXE ファイルを nph- で始まる名前にすることによって、その CGI プログラムが解析対象外ヘッダー モードで実行されるものであることをサーバーに示します。CGI には 2 つのモードがあります。通常のモード (解析対象ヘッダー) では、CGI 命令 (Content-type、Location、または Status) のいずれかを標準出力に送信する必要があります。送信した命令に基づいて、CGI によって有効な HTTP 応答行がフォーマットされます。その他の標準的な HTTP ヘッダーは自動的にフォーマットされ、指定したその他のヘッダーもすべて含まれます。

もう 1 つのモードは、解析対象外ヘッダー モードです。このモードでは、CGI 自体ではヘッダーの設定は行われません。応答行およびすべてのヘッダーを含む完全な HTTP 応答を CGI プログラムでフォーマットする必要があります。このモードでは、サーバーによるヘッダーの追加や修正は行われません。

規則では、名前が nph- で始まる CGI プログラムは解析対象外ヘッダー モードで実行され、それ以外の CGI プログラムは解析対象ヘッダー モードで実行されます。
状況
マイクロソフトでは、この問題をこの資料の冒頭に記載したマイクロソフト製品の問題として認識しています。
詳細

現象の再現手順

この CGI プログラムを Win32 Console Application としてコンパイルし、IIS サーバー上の実行可能なフォルダに入れます。
#include <stdio.h>int main(){  printf("Location: %s\r\n", "http://www.yahoo.com");  printf("Set-Cookie: Name1=Value1; path=/;expires=Fri, 22 May 1998 21:00:00 GMT\r\n\r\n");  return 0;}				

この CGI プログラムをブラウザから呼び出し、その出力を (ネットワーク モニタなどを使用して) 監視します。出力は以下のようになります。
HTTP/1.0 302 Object movedLocation: http://www.yahoo.comServer: Microsoft-IIS/2.0Content-Type: text/htmlContent-Length: 145<head><title>Document moved</title></head><body><h1>Object Moved</h1>This document may be found<a HREF="http://www.yahoo.com">here</a></body>				

IIS によって Set-Cookie ヘッダーが送信されていないことに注意してください。ブラウザで Cookie の警告を有効にした場合でも、警告は表示されません。

Cookie が 302 応答で設定されるようにするには、以下のようなコードを使用し、実行可能ファイルを nph- で始まる名前にします。
#include <stdio.h>int main(){  printf("HTTP/1.0 302 Redirect\r\n");  printf("Location: %s\r\n", "http://www.yahoo.com");  printf("Set-Cookie: Name=Value; path=/; expires=Fri, 22 May 1998 21:00:00   GMT\r\n\r\n");  return 0;}				

出力は以下のようになります。ここで Cookie が送信され、サーバーによるヘッダーの追加は行わないことに注意してください。
HTTP/1.0 302 RedirectLocation: http://www.yahoo.comSet-Cookie: Name=Value; path=/; expires=Fri, 22 May 1998 21:00:00 GMT				
関連情報
(c) Microsoft Corporation 1997, All Rights Reserved. Contributions by Leon Braginski, Microsoft Corporation
プロパティ

文書番号:176113 - 最終更新日: 12/05/2015 08:09:18 - リビジョン: 4.2

Microsoft Internet Information Server 3.0, Microsoft Internet Information Server 4.0, Microsoft Internet Information Services 5.0

  • kbnosurvey kbarchive kbbug kbnofix KB176113
フィードバック