Cookie について

Cookie はブラウザに保存されるデータの塊で、ウェブサイトが機能を実行するために必要な状態やその他の情報を保持するために使用されます。

Cookie とは、ウェブサイトがユーザーのマシンに保存する小さなファイルです。保存された情報は、ブラウザとウェブサイトの間でやり取りされます。

各 Cookie は Key-Value ペアで、Cookie が使用されるタイミングと場所を制御する複数の属性が含まれています。これらの属性は、有効期限の設定や、Cookie を HTTPS 経由でのみ送信する必要があることを示すために使用されます。Cookie は、HTTP ヘッダーまたは JavaScript インターフェースで設定できます。

Cookie は、ウェブサイトに永続状態を追加するために使用できる方法の一つです。長年にわたり機能は成長と進化を遂げましたが、プラットフォームには問題のあるレガシーの問題が残っています。この問題に対処するため、ブラウザ(Chrome、Firefox、Edge など)は、よりプライバシー保護に配慮したデフォルト設定を適用するように動作を変更しています。

Cookie の使用例

ブログで「最新情報」プロモーションをユーザーに表示したいとします。ユーザーはプロモーションを閉じることができ、閉じるとしばらくの間再び表示されなくなります。 設定を Cookie に保存し、1 か月(2,600,000 秒)で期限切れになるように設定して、HTTPS 経由でのみ送信できます。このヘッダーは次のようになります。

Set-Cookie: promo_shown=1; Max-Age=2600000; Secure
レスポンスでサーバーからブラウザに送信される 3 つの Cookie
サーバーは Set-Cookie ヘッダーを使用して Cookie を設定します。

読者がこれらの要件を満たすページ(安全な接続上にあり、Cookie の生成から 1 か月未満)を閲覧すると、ブラウザは次のヘッダーをリクエストに含めて送信します。

Cookie: promo_shown=1
リクエストでブラウザからサーバーに送信される 3 つの Cookie
ブラウザは Cookie ヘッダーで Cookie を返します。

また、document.cookie を使用して、そのサイトで使用可能な Cookie を JavaScript で追加、読み取ることもできます。document.cookie に代入すると、そのキーを持つ Cookie が作成またはオーバーライドされます。たとえば、ブラウザの JavaScript コンソールで次のことを試すことができます。

→ document.cookie = "promo_shown=1; Max-Age=2600000; Secure"
← "promo_shown=1; Max-Age=2600000; Secure"

document.cookie を読み取ると、現在のコンテキストでアクセス可能なすべての Cookie がセミコロンで区切られた状態で出力されます。

→ document.cookie;
← "promo_shown=1; color_theme=peachpuff; sidebar_loc=left"
ブラウザ内で Cookie にアクセスする JavaScript
JavaScript は document.cookie を使用して Cookie にアクセスできます。

人気のあるサイトをいくつか試してみると、ほとんどのサイトで 3 個を超える Cookie が設定されていることがわかります。ほとんどの場合、これらの Cookie は、そのドメインへのリクエストごとに送信されます。これにはいくつかの影響があります。多くの場合、アップロード帯域幅はダウンロードよりも制限されているため、すべてのアウトバウンド リクエストのオーバーヘッドによって、最初のバイトまでの時間が遅延します。設定する Cookie の数とサイズは控えめにします。Cookie が必要以上に長く保持されないように、Max-Age 属性を使用してください。

ファーストパーティ Cookie とサードパーティ Cookie とは

以前に閲覧したサイトに戻ると、現在アクセスしているサイトだけでなく、さまざまなドメインの Cookie が存在していることに気付くでしょう。現在のサイトのドメイン(ブラウザのアドレスバーに表示されるドメイン)と一致する Cookie は、ファーストパーティ Cookie と呼ばれます。同様に、現在のサイト以外のドメインからの Cookie はサードパーティ Cookie と呼ばれます。これは絶対的なラベルではなく、ユーザーのコンテキストに関連するラベルです。同じ Cookie が、ユーザーが現在アクセスしているサイトに応じてファースト パーティまたはサードパーティのいずれかになります。

同じページの異なるリクエストからブラウザに送信される 3 つの Cookie
Cookie は、1 つのページ上のさまざまなドメインから取得される場合があります。

上記の例を続けます。あるブログ投稿に、特に素晴らしい猫の写真が含まれていて、/blog/img/amazing-cat.png でホストされているとします。とても素晴らしい画像なので、別のユーザーが自分のサイトで直接使用します。あるユーザーがブログにアクセスして promo_shown Cookie を保持している場合、そのユーザーが他のユーザーのサイトで amazing-cat.png を閲覧すると、その画像のリクエストでその Cookie が送信されます。これは、promo_shown はこの他のユーザーのサイトで何も使用されておらず、リクエストのオーバーヘッドを追加するだけなので、特に有用ではありません。

これが意図しない結果であるのであれば、なぜこのような処理を行いますか。このメカニズムにより、サイトはサードパーティのコンテキストで使用されている場合でも状態を維持できます。たとえば、サイトに YouTube 動画を埋め込むと、プレーヤーに [後で見る] オプションが表示されます。訪問者がすでに YouTube にログインしている場合、そのセッションはサードパーティ Cookie によって埋め込みプレーヤーで利用できます。つまり、[後で見る] ボタンをクリックすると、動画を一度に保存するだけで済みます。ユーザーにログインを求めたり、ページから移動して YouTube に移動したりする必要はありません。

同じ Cookie が 3 つの異なるコンテキストで送信されている
サードパーティ コンテキストの Cookie は、別のページにアクセスしたときに送信されます。

ウェブの文化的特性の一つは、デフォルトでオープンになる傾向があることです。これが、多くのユーザーが独自のコンテンツやアプリを作成できる理由のひとつです。しかし、これにより、セキュリティとプライバシーに関する多くの懸念も生じています。クロスサイト リクエスト フォージェリ(CSRF)攻撃は、リクエストを開始したユーザーに関係なく、特定の送信元へのリクエストに Cookie が付加されるという事実を利用します。たとえば、evil.example にアクセスすると、your-blog.example へのリクエストがトリガーされ、ブラウザは関連する Cookie を正常に添付します。ブログでこれらのリクエストの検証方法に注意を払っていない場合、evil.example によって投稿の削除や独自のコンテンツの追加などのアクションがトリガーされる可能性があります。

また、Cookie を使用して複数のサイトでユーザーのアクティビティをトラッキングする方法に対するユーザーの意識も高まっています。ただし、これまで Cookie でインテントを明示的に指定する方法はありませんでした。promo_shown Cookie はファーストパーティ コンテキストでのみ送信する必要があります。一方、他のサイトに埋め込むことを目的としたウィジェットのセッション Cookie は、サードパーティ コンテキストでログイン状態を提供するために意図的に存在します。

適切な SameSite 属性を設定することで、Cookie の目的を明示的に指定できます。

ファーストパーティ Cookie を特定して適切な属性を設定する方法については、ファーストパーティ Cookie のレシピをご覧ください。