| インターネット技術標準化委員会 (IETF) | A. Barth |
| Request for Comments: 6265 | U.C. Berkeley |
| 廃止対象: 2965 | 2011年4月 |
| カテゴリ: 標準化トラック | |
| ISSN: 2070-1721 |
HTTP ステート管理メカニズム
概要
本書は HTTP の Cookie および Set-Cookie ヘッダーフィールドを定義します。これらのヘッダーフィールドは、HTTP サーバーが HTTP ユーザーエージェントに状態(クッキーと呼ばれる)を保存させるために使用でき、主にステートレスな HTTP プロトコル上で状態を持つセッションを維持することを可能にします。クッキーにはセキュリティやプライバシーを低下させる歴史的な不都合が多くありますが、Cookie および Set-Cookie ヘッダーフィールドはインターネット上で広く使用されています。本書は RFC 2965 を廃止します。
このメモのステータス
これはインターネット標準化トラック文書です。
本書はインターネット技術標準化委員会(IETF)の成果物です。本書は IETF コミュニティの合意を表しています。公開のために一般レビューを経て、インターネット技術運営指導グループ(IESG)によって承認されています。インターネット標準に関する詳細は RFC 5741 のセクション2 を参照してください。
本書の現在のステータス、正誤表、フィードバックの提供方法などの情報は http://www.rfc-editor.org/info/rfc6265 で入手できます。
Copyright Notice
Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.
1. はじめに
本書は HTTP の Cookie と Set-Cookie ヘッダーフィールドを定義します。Set-Cookie ヘッダーフィールドを使用して、HTTP サーバーは名前/値のペアと関連メタデータ(クッキーと呼ばれる)をユーザーエージェントに渡すことができます。ユーザーエージェントがその後サーバーに行うリクエストでは、ユーザーエージェントはメタデータやその他の情報を使って、Cookie ヘッダーに名前/値のペアを返すかどうかを判断します。
表面的には単純ですが、クッキーには多くの複雑さがあります。例えば、サーバーはクッキーを送信する際に各クッキーのスコープを示します。スコープは、ユーザーエージェントがクッキーを返すべき最大の期間、クッキーを返すべきサーバー、およびクッキーが適用される URI スキームを示します。
歴史的な理由から、クッキーにはいくつかのセキュリティおよびプライバシー上の不都合があります。例えば、サーバーはあるクッキーが「Secure」接続向けであることを示すことができますが、Secure 属性は能動的なネットワーク攻撃者の存在下で完全性を提供するものではありません。同様に、あるホスト向けのクッキーは、そのホストのすべてのポートで共有されますが、通常のブラウザの「同一生成元ポリシー」は異なるポート経由で取得されたコンテンツを分離します。
本仕様には二つの対象読者がいます: クッキーを生成するサーバーの開発者と、クッキーを消費するユーザーエージェントの開発者です。
ユーザーエージェントとの相互運用性を最大化するために、サーバーはクッキーを生成する際に セクション4 で定義された良好なプロファイルに従うことを SHOULD 推奨します。
ユーザーエージェントは、既存の良好でないサーバー挙動とも相互運用性を最大化するために、セクション5 で定義されたより寛容な処理規則を MUST 実装しなければなりません。
本書は、インターネット上で実際に使われている Cookie と Set-Cookie ヘッダーの構文と意味を規定します。特に、本書は今日使われているものを超える新たな構文や意味を作成するものではありません。セクション4 に示したクッキー生成に関する推奨は、現在のサーバー挙動の望ましい部分集合を表しています。さらに、セクション5 のより寛容なクッキー処理アルゴリズムも、今日使われているすべての構文的・意味的変種を推奨するものではありません。既存ソフトウェアが推奨プロトコルと大きく異なる場合は、その差異を説明する注記を文書内に含めています。
本書の前には少なくとも三つのクッキーの記述がありました: いわゆる「Netscape cookie specification」[Netscape]、RFC 2109 [RFC2109]、および RFC 2965 [RFC2965]。しかし、これらのいずれの文書もインターネット上で実際に Cookie と Set-Cookie ヘッダーがどのように使われているかを記述していません(歴史的文脈については [Kri2001] を参照)。本書は以前の IETF による HTTP 状態管理機構の仕様に関連して以下の措置を要求します:
- RFC2109 の状態を Historic に変更する(既に RFC2965 によって廃止されています)。
- RFC2965 の状態を Historic に変更する。
- RFC2965 が本書によって廃止されたことを示す。
特に、RFC 2965 を Historic に移し廃止することにより、本書は Cookie2 および Set-Cookie2 ヘッダーフィールドの使用を非推奨とします。
2. 規約
2.1. 適合基準
本書におけるキーワード "MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY"、および "OPTIONAL" は [RFC2119] に従って解釈されます。
アルゴリズムの一部として命令形で表現された要件(例えば "先頭の空白文字を取り除く" や "false を返してこれらの手順を中止する" など)は、導入部で使用されたキーワード("MUST"、"SHOULD"、"MAY" 等)の意味で解釈されます。
アルゴリズムや特定の手順として表現された適合要件は、最終結果が同等であれば任意の方法で実装できます。特に、本仕様で定義されたアルゴリズムは理解しやすくすることを目的としており、性能を目的としたものではありません。
2.2. 構文表記法
本仕様は拡張バックゥス・ナウア形式(ABNF)表記を [RFC5234] の記法で使用します。
以下のコアルールは参照として含まれます([RFC5234]、付録B.1 参照): ALPHA(文字)、CR(キャリッジリターン)、CRLF(CR LF)、CTL(制御文字)、DIGIT(10進 0-9)、DQUOTE(ダブルクォート)、HEXDIG(16進 0-9/A-F/a-f)、LF(ラインフィード)、NUL(ヌルオクテット)、OCTET(NUL を除く任意の 8 ビットデータ列)、SP(空白)、HTAB(水平タブ)、CHAR(任意の [USASCII] 文字)、VCHAR(可視 [USASCII] 文字)、および WSP(空白文字).
OWS(optional whitespace)ルールは 0 個以上の線形空白文字が現れてよい場所で使用されます。:
OWS = *( [ obs-fold ] WSP )
; "optional" whitespace
obs-fold = CRLF
OWS は生産しないか、あるいは単一の SP 文字として生産することが SHOULD 推奨されます。
2.3. 用語
用語 user agent、client、server、proxy、および origin server は HTTP/1.1 仕様([RFC2616]、セクション1.3)での意味と同じです。
request-host は、ユーザーエージェントが HTTP リクエストを送信している(あるいは HTTP レスポンスを受信している)ホストの名前です(すなわち、対応する HTTP リクエストを送信したホストの名前)。
request-uri の用語は RFC2616 セクション5.1.2 に定義されています。
二つのオクテット列が大文字小文字を区別せずに一致すると言えるのは、[RFC4790] に定義された i;ascii-casemap 照合の下で等価である場合に限ります。
文字列(string)とは非 NUL オクテットの列を意味します。
3. 概要
このセクションは、オリジンサーバーがユーザーエージェントに状態情報を送信し、ユーザーエージェントがその状態情報をオリジンサーバーに返す方法の概略を示します。
状態を保存するために、オリジンサーバーは HTTP レスポンスに Set-Cookie ヘッダーを含めます。以後のリクエストでは、ユーザーエージェントは以前に受け取った Set-Cookie ヘッダー内のクッキーを含む Cookie リクエストヘッダーをオリジンサーバーに返します。オリジンサーバーは Cookie ヘッダーを無視してもよく、その内容をアプリケーション定義の目的のために使用しても構いません。
オリジンサーバーは任意のレスポンスに Set-Cookie 応答ヘッダーを送信することが MAY 許されています。ユーザーエージェントは 100 レベルのステータスコードを持つレスポンスに含まれる Set-Cookie ヘッダーを無視することが MAY 許されていますが、その他のレスポンス(400 や 500 レベルを含む)に含まれる Set-Cookie ヘッダーは処理しなければならないことが MUST 指定されています。オリジンサーバーは一つのレスポンスに複数の Set-Cookie ヘッダーフィールドを含めることができます。Cookie または Set-Cookie ヘッダーフィールドの存在は、HTTP キャッシュがレスポンスを保存および再利用することを妨げるものではありません。
オリジンサーバーは複数の Set-Cookie ヘッダーフィールドを単一のヘッダーフィールドに折りたたむべきではありません SHOULD NOT。HTTP ヘッダーフィールドの折りたたみ(RFC2616 の定義など)を使うと、Set-Cookie の %x2C (",") 文字の使用と衝突し、Set-Cookie ヘッダーフィールドの意味が変わる可能性があります。
3.1. 例
Set-Cookie ヘッダーを使って、サーバーは短い文字列を HTTP レスポンスでユーザーエージェントに送り、それをユーザーエージェントが将来のスコープ内の HTTP リクエストで返すようにできます。例えば、サーバーは名前 SID、値 31d4d96e407aad42 の「セッション識別子」をユーザーエージェントに送ることができます。ユーザーエージェントはその後のリクエストでそのセッション識別子を返します。
== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
サーバーは Path および Domain 属性を使用してクッキーのデフォルトスコープを変更できます。例えば、サーバーはユーザーエージェントに対し example.com のすべてのパスおよびすべてのサブドメインに対してクッキーを返すよう指示できます。
== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
次の例に示すように、サーバーはユーザーエージェントに複数のクッキーを保存させることができます。例えば、サーバーはセッション識別子とユーザーの選好言語の両方を保存するために二つの Set-Cookie ヘッダーフィールドを返すことができます。セッション識別子のような機微な情報には Secure および HttpOnly 属性を使用して追加のセキュリティ保護を提供している点に注目してください(セクション4.1.2 を参照)。
== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US
上記の Cookie ヘッダーには SID と lang の二つのクッキーが含まれていることに注意してください。サーバーがユーザーエージェントにクッキーを複数回の「セッション」(例えばユーザーエージェントの再起動)に渡って保持させたい場合、サーバーは Expires 属性で有効期限を指定できます。なお、ユーザーエージェントがクッキーストアの割当てを超えた場合やユーザーが手動でクッキーを削除した場合には、ユーザーエージェントが有効期限より前にクッキーを削除する可能性がある点に注意してください。
== Server -> User Agent ==
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US
最後に、クッキーを削除するには、サーバーは過去の日付を持つ Expires を指定した Set-Cookie ヘッダーを返します。サーバーがクッキーの削除に成功するのは、Set-Cookie ヘッダーの Path と Domain 属性がクッキー作成時に使用された値と一致する場合に限ります。
== Server -> User Agent ==
Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
4. サーバー要件
この節では、Cookie および Set-Cookie ヘッダの良好なプロファイルの構文と意味を説明します。
5. ユーザーエージェント要件
この節は Cookie および Set-Cookie ヘッダを実装可能な詳細で定めています。これらの要件を正確に実装するユーザーエージェントは、良好なプロファイルに従わない既存のサーバーとも相互運用できます。
ユーザーエージェントは、より厳格な制約を実装することもできます(例えばセキュリティ向上のため)。しかし実験により、そのような厳格性は既存サーバーとの相互運用性を低下させることが示されています。
5.1. サブコンポーネントアルゴリズム
この節では、ユーザーエージェントが Cookie および Set-Cookie ヘッダの特定サブコンポーネントを処理するために使用するいくつかのアルゴリズムを定義します。
5.3. ストレージモデル
ユーザーエージェントは各クッキーについて次のフィールドを保存します: name, value, expiry-time, domain, path, creation-time, last-access-time, persistent-flag, host-only-flag, secure-only-flag, http-only-flag。
ユーザーエージェントが request-uri から name cookie-name、value cookie-value、attributes cookie-attribute-list のクッキーを "受け取った" とき、ユーザーエージェントは次のように処理しなければなりません MUST:
- ユーザーエージェントは受け取ったクッキーを完全に無視してもよい MAY。例えば、サードパーティのレスポンスからのクッキー受領をブロックしたり、サイズ超過のクッキーを保存しないことがある。
- 新しいクッキーを作成し name と value を設定する。creation-time と last-access-time を現在日時に設定する。
- もし cookie-attribute-list に "Max-Age" 属性が含まれているなら:
- persistent-flag を true にする。
- cookie-attribute-list 内で最後に現れる "Max-Age" 属性の attribute-value を expiry-time に設定する。
- persistent-flag を true にする。
- cookie-attribute-list 内で最後に現れる "Expires" 属性の attribute-value を expiry-time に設定する。
- persistent-flag を false にする。
- expiry-time を最新の表現可能日時に設定する。
- もし cookie-attribute-list に "Domain" 属性があるなら:
- domain-attribute を cookie-attribute-list 内で最後に現れる "Domain" 属性の attribute-value にする。
- domain-attribute を空文字列にする。
- ユーザーエージェントが "public suffix" を拒否するよう設定されていて、domain-attribute が public suffix の場合:
- もし domain-attribute が正規化された request-host と同一なら:
- domain-attribute を空文字列にする。
- クッキーを完全に無視して処理を中止する。
- 注: "public suffix" は "com", "co.uk", "pvt.k12.wy.us" のような公開レジストリで管理されるドメインです。可能であれば最新の public suffix リスト(例: Mozilla の <http://publicsuffix.org/>)を使用することが推奨されます SHOULD。
- もし domain-attribute が正規化された request-host と同一なら:
- もし domain-attribute が非空なら:
- 正規化された request-host が domain-attribute に domain-match しない場合:
- クッキーを完全に無視して処理を中止する。
- host-only-flag を false に設定する。
- cookie の domain を domain-attribute に設定する。
- host-only-flag を true に設定する。
- cookie の domain を正規化された request-host に設定する。
- 正規化された request-host が domain-attribute に domain-match しない場合:
- もし cookie-attribute-list に "Path" 属性が含まれるなら、cookie の path を cookie-attribute-list 内で最後に現れる "Path" の attribute-value に設定する。そうでなければ cookie の path を request-uri の default-path に設定する。
- もし cookie-attribute-list に "Secure" 属性が含まれるなら cookie の secure-only-flag を true に、含まれないなら false に設定する。
- もし cookie-attribute-list に "HttpOnly" 属性が含まれるなら cookie の http-only-flag を true に、含まれないなら false に設定する。
- もしクッキーが "非 HTTP" API から受け取られ、かつ cookie の http-only-flag が設定されている場合、処理を中止してクッキーを完全に無視する。
- クッキーストアに同じ name, domain, path を持つクッキーが存在する場合:
- old-cookie を既存の該当クッキーとする(このアルゴリズムは同一の name/domain/path を持つクッキーが最大1つであることを保証する)。
- もし新しいクッキーが非 HTTP API から受け取られ old-cookie の http-only-flag が設定されている場合、処理を中止して新しいクッキーを無視する。
- 新しいクッキーの creation-time を old-cookie の creation-time に合わせる。
- old-cookie をクッキーストアから削除する。
- 新しいクッキーをクッキーストアに挿入する。
クッキーは expiry-date が過去であれば "expired" と見なされます。
ユーザーエージェントは、クッキーストアに期限切れクッキーが存在する場合、すべての期限切れクッキーを削除しなければなりません MUST。
任意の時点で、ドメインを共有するクッキー数が実装定義の上限(例えば 50 個)を超える場合、ユーザーエージェントは過剰クッキーを削除してもよい MAY。
任意の時点で、クッキーストアが予め定めた上限(例えば 3000 個)を超えた場合、ユーザーエージェントは過剰クッキーを削除してもよい MAY。
ユーザーエージェントが過剰クッキーを削除する場合、次の優先順でクッキーを削除しなければなりません MUST:
- 期限切れクッキー。
- 同じドメインフィールドを共有するクッキーの数が規定値を超えるもの。
- それ以外の全てのクッキー。
同じ削除優先度のクッキーが複数ある場合、ユーザーエージェントは last-access-date が最も古いクッキーを先に削除しなければなりません MUST。
"現在のセッションが終了する"(ユーザーエージェントの定義)とき、ユーザーエージェントは persistent-flag が false に設定されたすべてのクッキーをクッキーストアから削除しなければなりません MUST。
6. 実装に関する考慮事項
6.1. 制限
実際のユーザーエージェント実装には、保存可能なクッキーの数およびサイズに制限があります。一般的な用途のユーザーエージェントは、以下の最低限の能力をそれぞれ提供することがSHOULD推奨されます:
- クッキーあたり少なくとも 4096 バイト(クッキーの名前、値、および属性の長さの合計で測定)。
- ドメインごとに少なくとも 50 個のクッキー。
- 合計で少なくとも 3000 個のクッキー。
サーバーは、これらの実装上の制限に達するのを避け、また Cookie ヘッダーがすべてのリクエストに含まれることによるネットワーク帯域の最小化のために、可能な限り少数かつ小さなクッキーを利用することがSHOULD推奨されます。
ユーザーが指示した場合やメモリ圧迫などにより、ユーザーエージェントが任意のクッキーをいつでも削除する可能性があるため、サーバーはユーザーエージェントが Cookie ヘッダーで一つ以上のクッキーを返さなかった場合でも、適切にフォールバックするよう設計すべきである(優雅に劣化させることが)SHOULD推奨されます。
6.2. アプリケーションプログラミングインタフェース
Cookie および Set-Cookie ヘッダがこのような難解な構文を使う理由の一つは、多くのプラットフォーム(サーバー側とユーザーエージェント側の両方)が文字列ベースの API をクッキーに対して提供しており、アプリケーション層のプログラマが Cookie と Set-Cookie ヘッダで使われる構文の生成や解析を行う必要があるためです。多くのプログラマはこれを誤って実装し、相互運用性の問題を引き起こしてきました。
クッキーに対して文字列ベースの API を提供する代わりに、より意味的(セマンティック)な API を提供することはプラットフォームにとって有益です。本文書で具体的な API 設計を推奨することは範囲外ですが、シリアライズされた日付文字列の代わりに抽象的な "Date" オブジェクトを受け入れるといった利点は明らかです。
6.3. IDNA 依存と移行
IDNA2008 [RFC5890] は IDNA2003 [RFC3490] を置き換えます。しかし、両仕様間には差異があり、ドメイン名ラベルの処理(変換など)に差が生じる場合があります。IDNA2003 ベースのドメイン名ラベルが現存する移行期間がしばらく続くでしょう。ユーザーエージェントは IDNA2008 を実装することがSHOULD推奨され、IDNA 移行を支援するために [UTS46] や [RFC5895] を実装してもよい(MAY)です。もしユーザーエージェントが IDNA2008 を実装しないならば、ユーザーエージェントは IDNA2003 を実装しなければなりません(MUST)。
7. プライバシーに関する考慮事項
クッキーは、サーバーがユーザーを追跡する手段を提供するという点でしばしば批判されます。たとえば、多くの「ウェブ解析」会社は、ユーザーがある Web サイトに戻ってきたときや別のサイトを訪れたときにユーザーを認識するためにクッキーを使用します。クッキーは HTTP リクエスト間で永続化され、ホスト間で共有され得るため、追跡を容易にしますが、追跡のための唯一の手段ではありません。
7.2. ユーザーコントロール
ユーザーエージェントは、クッキーストア内のクッキーを管理するための仕組みをユーザーに提供することがSHOULD推奨されます。たとえば、指定した期間に受け取ったすべてのクッキーを削除したり、特定のドメインに関連するすべてのクッキーを削除したりする機能を提供できます。さらに、多くのユーザーエージェントはユーザーに保存されているクッキーを検査させる UI を提供しています。
ユーザーエージェントは、クッキーを無効化するための仕組みをユーザーに提供することがSHOULD推奨されます。クッキーが無効化されている場合、ユーザーエージェントは送信する HTTP リクエストに Cookie ヘッダを含めてはならず(MUST NOT)、受信した HTTP レスポンスの Set-Cookie ヘッダを処理してはなりません(MUST)。
一部のユーザーエージェントは、セッション間での永続的なクッキー保存を防ぐオプションをユーザーに提供します。そのように設定された場合、ユーザーエージェントは受け取ったすべてのクッキーを persistent-flag が false に設定されているかのように扱わなければなりません。多くの一般的なユーザーエージェントはこの機能を「プライベートブラウジング」モードとして提供しています([Aggarwal2010])。
一部のユーザーエージェントは、クッキーストアへの個々の書き込みを承認させる機能をユーザーに提供します。多くの一般的な利用シナリオでは、これらの制御は多数のプロンプトを生成しますが、プライバシー重視の一部のユーザーはこれらの制御を有用と感じることがあります。
7.3. 有効期限
サーバーはクッキーの有効期限を遠い未来に設定できますが、ほとんどのユーザーエージェントは実際に数十年にわたってクッキーを保持するわけではありません。恣意的に長過ぎる有効期限を選ぶのではなく、サーバーはクッキーの目的に基づいて適切な有効期限を選択し、ユーザーのプライバシーを促進することがSHOULD推奨されます。例えば、典型的なセッション識別子は 2 週間で失効するよう設定するのが合理的でしょう。
8. セキュリティに関する考慮事項
8.1. 概要
クッキーには多数のセキュリティ上の落とし穴があります。本節では、より顕著な問題点のいくつかを概観します。
特に、クッキーは開発者に認可(authorization)ではなく周辺権限(ambient authority)に依存するよう促すため、クロスサイトリクエストフォージェリ(CSRF)などの攻撃に脆弱になりがちです([CSRF])。また、セッション識別子をクッキーに保存する場合、開発者はセッション固定(session fixation)の脆弱性を生むことがよくあります。
Transport-layer の暗号化(HTTPS 等)は、ネットワーク攻撃者が被害者のクッキーを取得または改ざんするのを完全には防げません。なぜならクッキー・プロトコル自体に様々な脆弱性があるためです(下記の "弱い機密性" および "弱い完全性" を参照)。さらに、デフォルトではクッキーはネットワーク攻撃者からの機密性や完全性を保証しません(HTTPS と併用しても同様です)。
8.3. 平文
セキュアチャネル(TLS 等)を通じて送信されない限り、Cookie および Set-Cookie ヘッダの情報は平文で送信されます。
- これらのヘッダに含まれるすべての機密情報は盗聴者に露出します。
- 悪意のある中間者は、ヘッダを任意の方向に移動中に改ざんする可能性があり、予測不能な結果を招くことがあります。
- 悪意のあるクライアントは送信前に Cookie ヘッダを改変する可能性があり、予測不能な結果を招くことがあります。
サーバーはクッキーの内容を暗号化および署名することをSHOULD推奨します(サーバーが望む形式を用いて、ユーザーエージェントへ送信する際に)。しかし、クッキー内容の暗号化および署名は、攻撃者があるユーザーエージェントから別のユーザーエージェントへクッキーを移植したり、後で再生したりすることを防ぐものではありません。
すべてのクッキーの内容を暗号化および署名することに加えて、より高いレベルのセキュリティが要求される場合、サーバーは Cookie および Set-Cookie ヘッダをセキュアチャネル上のみで利用することをSHOULD推奨します。セキュアチャネルでクッキーを使用する場合、サーバーは全てのクッキーに Secure 属性を設定することをSHOULD推奨します(詳細は Section 4.1.2.5)。もしサーバーが Secure 属性を設定しなければ、セキュアチャネルによる保護は大部分が無効になります。
例えば、ウェブメールサーバーがセッション識別子をクッキーに保存し、通常 HTTPS でアクセスされるとします。サーバーがクッキーに Secure 属性を設定していない場合、能動的なネットワーク攻撃者はユーザーエージェントからのアウトバウンド HTTP リクエストを傍受してそのリクエストを webmail サーバーへの HTTP にリダイレクトできます。たとえ webmail サーバーが HTTP 接続を受け付けていなくても、ユーザーエージェントはリクエストにクッキーを含めます。能動的な攻撃者はこれらのクッキーを傍受し、サーバーに対して再生し、ユーザーのメール内容を窺い知ることができます。もしサーバーがクッキーに Secure 属性を設定していたなら、ユーザーエージェントは平文のリクエストにはクッキーを含めないため、このような問題は防げます。
8.4. セッション識別子
クッキーにセッション情報を直接保存する代わりに(攻撃者に露出・再生される恐れがあるため)、サーバーは一般にクッキーにノンス(または「セッション識別子」)を保存します。サーバーは、ノンスをキーとして関連する状態情報を参照できます。
セッション識別子クッキーを用いることで、攻撃者がクッキー内容を知った場合の損害を限定できます。ノンスはサーバーとの相互作用にのみ有用であり、クッキー自体に敏感な情報を含めるより安全です。さらに、単一のノンスを用いることで、攻撃者がサーバーとの二つのやり取りからクッキー内容を「継ぎ合わせる(splice)」ことを防ぎ、サーバーが予期せぬ動作をするのを防げます。
ただし、セッション識別子の使用にもリスクはあります。たとえば、サーバーは「セッション固定(session fixation)」の脆弱性を避けるために注意を払うべきです。セッション固定攻撃は三段階で進行します。まず攻撃者が自分のユーザーエージェントのセッション識別子を犠牲者のユーザーエージェントに移植します。次に犠牲者がその識別子を使用してサーバーとやり取りし、識別子にユーザーの資格情報や機密情報を付与する可能性があります。最後に攻撃者はその識別子を使って直接サーバーとやり取りし、ユーザーの権限や機密情報を得る場合があります。サーバーはこの種の脆弱性を避ける対策を講じるべきです(SHOULD)。
8.5. 弱い機密性
クッキーはポート単位での分離を提供しません。あるポートで読み取れるクッキーは、同じホストの別のポートで動作するサービスからも読み取れます。あるポートで書き込み可能なクッキーは、同じホストの別ポート上のサービスからも書き込み可能です。したがって、サーバーは同一ホストの異なるポートで相互に信頼しないサービスを実行し、それらの間でセキュリティに敏感な情報をクッキーで保存すべきではありません(SHOULD NOT)。
クッキーはスキームによる分離も提供しません。通常は http と https スキームで使われますが、同じホストのクッキーは ftp や gopher 等の他のスキームからも利用され得ます。このスキームによる分離の欠如は、HTML の document.cookie などの非 HTTP API でクッキーにアクセスできる場合に特に明白になりますが、処理要件自体にも存在します(例:gopher スキームで取得した URI を HTTP 経由で扱うことを考えてください)。
クッキーは常にパス単位での分離を提供するわけではありません。ネットワークレベルではあるパスのために保存されたクッキーは別のパスへ送信されませんが、一部のユーザーエージェントは HTML の document.cookie のような非 HTTP API を通じてクッキーを公開します。これらのユーザーエージェント(例えばウェブブラウザ)は異なるパスから取得したリソースを隔離しないため、あるパスから取得したリソースが別パス用に保存されたクッキーへアクセスできる場合があります。
8.6. 弱い完全性
クッキーは同一組織内の兄弟ドメイン(およびそのサブドメイン)に対する完全性保証を提供しません。例えば foo.example.com と bar.example.com を考えると、foo.example.com は Domain 属性に "example.com" を指定したクッキーを設定でき(場合によっては bar.example.com が設定した既存の "example.com" クッキーを上書きすることもあり得ます)、ユーザーエージェントはそのクッキーを bar.example.com への HTTP リクエストに含めます。最悪の場合、bar.example.com はそのクッキーを自分が設定したものと区別できなくなります。foo.example.com はこの能力を利用して bar.example.com に対する攻撃を仕掛ける可能性があります。
Set-Cookie ヘッダは Path 属性をサポートしていますが、Path 属性は任意の Path 属性を Set-Cookie ヘッダで受け入れるため、完全性保護を提供しません。例えば、http://example.com/foo/bar へのリクエストへの応答で Path 属性に "/qux" を指定したクッキーを設定できてしまいます。したがって、サーバーは同一ホストの異なるパスで相互に信頼しないサービスを実行し、クッキーに機密な情報を保存すべきではありません(SHOULD NOT)。
能動的なネットワーク攻撃者は、http://example.com/ からのレスポンスを偽装して Set-Cookie ヘッダを注入することで、https://example.com/ に送信される Cookie ヘッダへクッキーを挿入することも可能です。HTTPS の example.com サーバーは、これらのクッキーを HTTPS レスポンスで自身が設定したクッキーと区別できなくなります。能動的なネットワーク攻撃者はこの能力を使って、たとえ example.com が常に HTTPS を使用していても example.com に対する攻撃を仕掛ける可能性があります。
サーバーはクッキーの内容を暗号化および署名することでこれらの攻撃を部分的に軽減できます。しかし、暗号を用いるだけでは問題を完全に緩和できません。なぜなら攻撃者は正当な example.com サーバーから受け取ったクッキーを被害者のセッションで再生することが可能であり、予測不可能な結果を引き起こす可能性があるためです。
最後に、攻撃者は大量のクッキーを保存させることでユーザーエージェントにクッキーを削除させることができます。ユーザーエージェントが保存上限に達すると、いくつかのクッキーを強制的に削除しなければなりません。サーバーはユーザーエージェントがクッキーを保持し続けることを前提にしてはなりません(SHOULD NOT)。
8.7. DNS への依存
クッキーはセキュリティのために DNS に依存しています。DNS が部分的または完全に侵害された場合、クッキープロトコルはアプリケーションが要求するセキュリティ特性を提供できなくなる可能性があります。
9. IANA に関する考慮事項
恒久的なメッセージヘッダーフィールドのレジストリ([RFC3864]参照)は、以下の登録で更新されました。
10. 参照文献
10.1. 規範的参照文献
- [RFC1034]
- Mockapetris, P., “Domain names - concepts and facilities”, STD 13, RFC 1034, November 1987.
- [RFC1123]
- Braden, R., “Requirements for Internet Hosts - Application and Support”, STD 3, RFC 1123, October 1989.
- [RFC2119]
- Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
- [RFC2616]
- Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1”, RFC 2616, June 1999.
- [RFC3490]
- Faltstrom, P., Hoffman, P., and A. Costello, “Internationalizing Domain
Names in Applications (IDNA)”, RFC 3490, March 2003.
Section 6.3(IDNA 依存と移行)で、廃止された仕様への規範的参照がなぜ必要かの説明があります。 - [RFC4790]
- Newman, C., Duerst, M., and A. Gulbrandsen, “Internet Application Protocol Collation Registry”, RFC 4790, March 2007.
- [RFC5234]
- Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, January 2008.
- [RFC5890]
- Klensin, J., “Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework”, RFC 5890, August 2010.
- [USASCII]
- American National Standards Institute, “Coded Character Set -- 7-bit American Standard Code for Information Interchange”, ANSI X3.4, 1986.
10.2. 参考情報
- [RFC2109]
- Kristol, D. and L. Montulli, “HTTP State Management Mechanism”, RFC 2109, February 1997.
- [RFC2965]
- Kristol, D. and L. Montulli, “HTTP State Management Mechanism”, RFC 2965, October 2000.
- [RFC2818]
- Rescorla, E., “HTTP Over TLS”, RFC 2818, May 2000.
- [Netscape]
- Netscape Communications Corp., “Persistent Client State -- HTTP Cookies”, 1999, <http://web.archive.org/web/20020803110822/http://wp.netscape.com/newsref/std/cookie_spec.html>.
- [Kri2001]
- Kristol, D., “HTTP Cookies: Standards, Privacy, and Politics”, ACM Transactions on Internet Technology Vol. 1, #2, November 2001, <http://arxiv.org/abs/cs.SE/0105018>.
- [RFC3629]
- Yergeau, F., “UTF-8, a transformation format of ISO 10646”, STD 63, RFC 3629, November 2003.
- [RFC4648]
- Josefsson, S., “The Base16, Base32, and Base64 Data Encodings”, RFC 4648, October 2006.
- [RFC3864]
- Klyne, G., Nottingham, M., and J. Mogul, “Registration Procedures for Message Header Fields”, BCP 90, RFC 3864, September 2004.
- [RFC5895]
- Resnick, P. and P. Hoffman, “Mapping Characters for Internationalized Domain Names in Applications (IDNA) 2008”, RFC 5895, September 2010.
- [UTS46]
- Davis, M. and M. Suignard, “Unicode IDNA Compatibility Processing”, Unicode Technical Standards # 46, 2010, <http://unicode.org/reports/tr46/>.
- [CSRF]
- Barth, A., Jackson, C., and J. Mitchell, “Robust Defenses for Cross-Site Request Forgery”, 2008, <http://portal.acm.org/citation.cfm?id=1455770.1455782>.
- [Aggarwal2010]
- Aggarwal, G., Burzstein, E., Jackson, C., and D. Boneh, “An Analysis of Private Browsing Modes in Modern Browsers”, 2010, <http://www.usenix.org/events/sec10/tech/full_papers/Aggarwal.pdf>.
Appendix A. 謝辞
本書は RFC 2109 [RFC2109] を大いに参考にしています。我々はクッキーの仕様化に尽力した David M. Kristol と Lou Montulli に感謝します。特に David M. Kristol は IETF プロセスを乗り切る上で多大な助言を与えてくれました。本書に対する貴重なフィードバックをくれた Thomas Broyer、Tyler Close、Alissa Cooper、Bil Corry、corvid、Lisa Dusseault、Roy T. Fielding、Blake Frantz、Anne van Kesteren、Eran Hammer-Lahav、Jeff Hodges、Bjoern Hoehrmann、Achim Hoffmann、Georg Koppen、Dean McNamee、Alexey Melnikov、Mark Miller、Mark Pauley、Yngve N. Pettersen、Julian Reschke、Peter Saint-Andre、Mark Seaborn、Maciej Stachowiak、Daniel Stenberg、Tatsuhiro Tsujikawa、David Wagner、Dan Winship、Dan Witte の各氏に感謝します。