HTTP Cookie
- Cookie(クッキー / Web Cookie / ブラウザ Cookie) とは、サーバーがユーザーの Web ブラウザに送信する小さなデータ。
- HTTP プロトコルは ステートレス だが、 Cookie を使用することで、Web アプリケーションは限られた量のデータ(= 状態)を記憶することができる。
クッキーの用途
-
セッション管理
- ユーザーのログイン状態を維持する
- ショッピングカートの内容を保存する
- ゲームのスコアを保持する
-
パーソナライズ
- ユーザーの言語やUI設定を保持する
-
トラッキング
- ユーザー行動を記録・分析し、広告の表示回数をカウントする
ログインの流れ
- 「ブラウザ」は、「ユーザー」がフォームに入力したログイン情報(e.g. メールアドレス、パスワード)を「サーバー」に送信する。
- 「サーバー」は受け取ったログイン情報が正しい場合、UI をログイン後のものに更新し、「ブラウザ」に セッションIDを持つ Cookie を返す。
- 「ユーザー」が同じサイト内の別ページに移動すると、「ブラウザ」は、セッションIDを持つ Cookie と一緒に「サーバー」にリクエストを送信する。
- 「サーバー」はセッションID をチェックし、以下のいずれかの結果を返す。
- セッションID が有効である場合、「サーバー」は「ブラウザ」上に新しいページを返す。
- セッションID が有効でない場合、「サーバー」はセッション ID を削除し、「ブラウザ」上に「アクセスが拒否されました」というメッセージを表示し、「ユーザー」に再ログインを求める。
Cookie 以外のクライアントストレージ
- Webの初期の頃は、クライアント(ブラウザ)側でデータを保存するためには Cookie を使用するしかなかった。
- 現在では、以下のような最新のストレージ API が推奨される。
-
Web Storage API
-
localStorage
- ブラウザを閉じてもデータを保持することができる
-
sessionStorage
- ブラウザを閉じるとデータが消える
-
localStorage
-
IndexedDB
- 大容量の構造化データを保存・管理するためのデータベース
-
Web Storage API
Cookie のデメリット
-
容量と数の制限
- ブラウザでは、ドメインごとに保持できる「Cookie」の数は 数百 程度で、1つあたりの最大サイズは 4KB 。
- 一方、Web Storage API や IndexedDB では、より大量のデータを保存できる。
-
パフォーマンスの低下
- Cookie はリクエストごとに送信されるため、Cookie の数が多い場合はパフォーマンスが低下する可能性がある
注: ブラウザに保存された Cookie やその他のストレージを確認するには、以下を使用する。
- Firefox Developer Toolsの Storage Inspector
- Chrome DevToolsの Application Pannel
Cookie の作成、削除、更新
Set-Cookie
レスポンスヘッダー
- サーバーは、HTTPリクエストを受信すると、1つ以上の
Set-Cookie
ヘッダーを含めてレスポンスを送信することができる。 - これにより、 ブラウザに Cookie を設定する ことができる。
Set-Cookie
ヘッダーは、個別の Cookie を「名前」と「値」のペアで設定する。
Set-Cookie: <cookie-name>=<cookie-value>
ブラウザに2つの Cookie を保存するためのレスポンスの例:
HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=chocolate
Set-Cookie: tasty_cookie=strawberry
[page content]
注: 各サーバーサイド言語・フレームワークの Set-Cookie
ヘッダーの使用方法を確認してください。
Ruby on Rails
- リクエストからの参照:
class SessionsController < ApplicationController
def show
session_id = cookies.encrypted[:session_id]
puts session_id # => abc123def456
render plain: "Check"
end
end
- レスポンスへの設定:
class SessionsController < ApplicationController
def create
cookies.encrypted[:session_id] = {
value: 'abc123def456',
path: '/',
httponly: true,
secure: true,
same_site: :strict,
expires: 1.hour.from_now
}
render plain: "OK"
end
end
Python
- リクエストからの参照:
def check_cookie_view(request):
session_id = request.COOKIES.get('session_id')
print(session_id) # => abc123def456
return HttpResponse('Check')
- レスポンスへの設定:
from django.http import HttpResponse
def set_cookie_view(request):
response = HttpResponse('OK')
response.set_cookie(
'session_id',
'abc123def456',
max_age=3600,
secure=True,
httponly=True,
samesite='Strict',
path='/'
)
return response
Node.js(Hono)
- リクエストからの参照 / レスポンスへの設定:
import { Hono } from 'hono'
import { getCookie, setCookie } from 'hono/cookie'
const app = new Hono()
// リクエストからの参照
app.get('/check', (c) => {
const sessionId = getCookie(c, 'session_id')
console.log(sessionId) // => abc123def456
return c.text('Check')
})
// レスポンスへの設定
app.get('/', (c) => {
setCookie(c, 'session_id', 'abc123def456', {
path: '/',
httpOnly: true,
secure: true,
sameSite: 'Strict',
maxAge: 3600
})
return c.text('OK')
})
export default app
Go
- リクエストからの参照:
func checkHandler(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session_id")
if err == nil {
println(cookie.Value) // => abc123def456
}
w.Write([]byte("Check"))
}
- レスポンスへの設定:
package main
import (
"net/http"
"time"
)
func handler(w http.ResponseWriter, r *http.Request) {
http.SetCookie(w, &http.Cookie{
Name: "session_id",
Value: "abc123def456",
Path: "/",
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteStrictMode,
MaxAge: 3600,
})
w.Write([]byte("OK"))
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":3000", nil)
}
Cookie
リクエストヘッダー
- ブラウザは、HTTPリクエストを送信するとき、現在のドメインでブラウザに保存されている Cookie を
Cookie
ヘッダー内に含め、サーバーに送り返す。
GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=chocolate; tasty_cookie=strawberry
Cookie の削除
- Cookie の削除は、
Expires
属性 の値を過去に設定するか、Max-Age
属性を 0 に設定することによって実現できる。 - Cookie の作成時に
Set-Cookie
ヘッダー内にこれらの属性を設定するかどうかによって、
「永続的な Cookie」または「セッション Cookie」に分類される。
永続的な Cookie
-
Expires
属性またはMax-Age
属性で、指定された期限以降に削除される Cookie のこと
Expires
属性
Set-Cookie: id=a3fWa; Expires=Thu, 31 Oct 2021 07:28:00 GMT;
Max-Age
属性
Set-Cookie: id=a3fWa; Max-Age=2592000
注:
-
Expires
属性は特定の日時を指定する。 -
Max-Age
属性は現在時刻からの秒数を指定する。 - 両方が設定されている場合は
Max-Age
属性が優先される。- この理由は、
Expires
属性は、Cookie が設定されたクライアントに対して相対的な日時であるため。 - もしサーバーが異なった日時を指定していると、
Expires
属性ではエラーが発生する可能性がある。
- この理由は、
セッション Cookie
-
Expires
属性またはMax-Age
属性がない Cookie のこと -
現在のセッションが終了すると削除される
- 一般には、ブラウザを閉じると削除
- 「現在のセッション」が終了するタイミングは、「ブラウザ」によって定義される。
- Chromeなど一部のブラウザは、再起動時にセッション復元機能を提供している。
- これにより、セッション Cookie がいつまでも有効な状態になってしまう問題が発生する可能性がある。
注:
- サイトがユーザーを認証する場合は、ユーザーが認証するたびに、(すでにセッション Cookie が存在していたとしても)セッション Cookie を再作成し、再送信する必要がある。
- これにより、第三者がユーザーのセッションを再利用できる セッション固定攻撃 を防ぐことができる。
ゾンビ Cookie / スーパークッキー
- ユーザーが自身のセキュリティのためにブラウザの Cookie を削除した場合でも、Webサイトの運営者がブラウザに残った情報から Cookie を復元したり、ユーザーの行動をトラッキングする手法のこと。
- ユーザーのプライバシーと制御の原則に違反し、データプライバシー規制に違反する可能性があり、それらを使用する Web サイトは法的責任を負う場合もある。
Cookie の値の更新
- Cookie を更新するには、サーバーがレスポンスを返す際の
Set-Cookie
ヘッダーで、「既存の Cookie の名前」と「新しい値」を設定する。
Set-Cookie: id=new-value
Cookie の値の更新を行いたいケース
- ユーザーが環境設定を更新し、アプリケーションがクライアント側データに変更を反映させたい場合など。
- 例1. ユーザーがテーマを「ライトモード」から「ダークモード」に変更した際に、その設定を Cookie に保存する。
-
Web Storage API を使用して、
localStorage
やsessionStorage
に設定を保存することも可能。
JavaScript 経由で Cookie を更新する
-
HttpOnly
属性が設定されていない場合 (かつ、サーバーからSet-Cookie
ヘッダーで Cookie が設定されていた場合)は、JavaScript を使用して Cookie の値を読み書きすることができる。-
Document.cookie
プロパティ を使用して Cookie を設定、取得できる - Cookie Store API を使用して非同期的に Cookie を管理できる
-
console.log(document.cookie);
// logs "yummy_cookie=chocolate; tasty_cookie=strawberry"
document.cookie = "yummy_cookie=blueberry";
console.log(document.cookie);
// logs "tasty_cookie=strawberry; yummy_cookie=blueberry"
注:
-
HttpOnly
属性が設定された Cookie は、JavaScript からアクセスできない。 -
SameSite
属性が設定されている場合、クロスサイトリクエスト時の Cookie 送信が制限される。 -
fetch()
やXMLHttpRequest
などの同一オリジンポリシーにより、クロスサイトリクエストでの Cookie の送信や更新が制限される。
セキュリティ
- Cookie に情報を格納した場合、デフォルトではすべての Cookie の値がユーザーに表示され、ユーザーは Cookie の値を変更することができてしまう。
- しかし、 Cookie が悪用されることは絶対に避けなければならない。
- 犯罪者がユーザーのセッションIDを盗み、犯罪者はそのセッションIDを使用して犯罪者自身の Cookie を設定し、別のユーザーとしてログインしているように見せかけ、その過程で別のユーザーの銀行や電子商取引のアカウントを乗っ取ることもできる。
Cookie へのアクセスを制限する
- Cookie が安全に送信され、意図しない第三者やスクリプトからアクセスされないようにするには、
Secure
属性とHttpOnly
属性の 2つの方法がある。
Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly
Secure
属性
- HTTPS プロトコル上で暗号化されたリクエストでのみサーバーに送信される。
- (localhost を除いて) 安全でない HTTP では決して送信されないため、中間者攻撃の攻撃者が簡単にアクセスすることはできないようになる。
- URL に(
https:
ではなく)http:
とついている安全でないサイトには、Secure
属性を持つ Cookie を設定することができない。 - ただし、
Secure
属性によって Cookie 内の機密情報へのアクセスをすべて防げるわけではない。- クライアントのハードディスクへのアクセス
- HttpOnly 属性が設定されていない場合の JavaScript 経由でのアクセス
HttpOnly
属性
-
JavaScript 経由で Cookie にアクセスすることを禁止する。
-
Document.cookie
などを使用して Cookie を操作することができなくなり、サーバーのSet-Cookie
を通じてのみアクセスすることができるようになる。 - ユーザーのセッションを維持するための Cookie は
HttpOnly
属性をつけるべきであり、JavaScript 経由でアクセスできることは全く安全ではない。
-
- これにより、クロスサイトスクリプティング(XSS)攻撃の影響が軽減される。
注:
Webアプリケーションでは、ユーザーの機密情報(例: パスワード、個人識別情報、支払い情報など)を Cookie に直接保存することはセキュリティ上のリスクがあるため、避けるべき。
機密情報を扱うには、以下のような方法が推奨される。
1. セッションID
- セッションIDは、ユーザーごとに一意に生成されるランダムな文字列。
- これを Cookie に保存することで、実際の機密情報をクライアント側に保持せずに済む。
- サーバー側でセッションIDとユーザーの情報を対応付けるため、セッションIDが漏洩しても直接的な機密情報の漏洩を防ぐことができる。
Set-Cookie: session_id=abc123xyz; Path=/; HttpOnly; Secure; SameSite=Strict
2. JSON Web Token (JWT)
- JSON Web Token (JWT)は、ヘッダー、ペイロード、署名から構成され、1つのトークンとしてエンコードされたもの。
- サーバーはトークン内の情報を検証し、ユーザーの認証状態を確認することができる。
Set-Cookie: auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...; Path=/; HttpOnly; Secure; SameSite=Strict
Cookie の送信先(スコープ)を定義する
-
Domain
属性とPath
属性は、「ブラウザが、どのサーバーのドメイン・パスに対して Cookie を送受信するか」を制御する。
Domain
属性
- サーバーは
Set-Cookie
ヘッダーのDomain
属性に、自身のドメインまたはその親ドメインのみ を設定できる。 - ブラウザは
Domain
属性に指定されたドメインとそのサブドメインにのみ、Cookie をCookie
ヘッダーに含めてリクエストを送信することができる。- 例1:
mozilla.org
というドメインを持つサーバーが、Set-Cookie
ヘッダーにDomain=mozilla.org
を指定してレスポンスを返した場合、ブラウザはそのドメインmozilla.org
とそのサブドメインdeveloper.mozilla.org, etc
に対してのみCookie
ヘッダーに Cookie を指定してリクエストを送信することができる。 - 例2:
foo.example.com
というドメインを持つサーバーは、Domain
属性をexample.com
かfoo.example.com
に設定できるが、bar.foo.example.com
やelsewhere.co
に設定することはできない。
ただし、Cookie はbar.foo.example.com
などのサブドメインには送信される。
- 例1:
Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Domain=mozilla.org
Domain
属性が指定されていない場合
- サーバーが
Set-Cookie
ヘッダーの Domain 属性を指定しなかった場合、ブラウザは、Cookie をそのサーバーのホスト(完全一致するドメインmozilla.org
)にリクエストを送信する際にのみ使用する Host-Only Cookie として保存する。-
そのサブドメイン(
developer.mozilla.org
)に対してはリクエストを送信できなくなる ため、セキュリティが向上する
-
そのサブドメイン(
- See also: 不正なドメイン - Set-Cookie - MDN
Path
属性
- サーバーは
Set-Cookie
ヘッダーのPath
属性を指定すると、ブラウザはPath
属性で指定されたURLパスの範囲に対してのみ、Cookie ヘッダーに Cookie を指定してリクエストを送信することができる。 -
%x2F
("/") という文字はディレクトリの区切り文字とみなされるため、サブディレクトリも一致する。- たとえば、
Path=/docs
を設定すると、次のリクエストパスが一致する。/docs
/docs/
/docs/Web/
/docs/Web/HTTP
- 次のリクエストパスは一致しない。
/
/docsets
/fr/docs
- たとえば、
Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Path=/docs
クロスサイトリクエストフォージェリ(CSRF / Cross-Site Request Forger)対策
クロスサイトリクエスト(Cross-Site Request)
- ユーザーが、現在アクセスしているサイトとは異なる 意図しないサイトに対してリクエストを送信してしまうこと 。
- 例1.
- ユーザーが SNS(例:
twitter.com
)で共有されている「Amazon 商品ページ」へのリンクを見つける。 - そのリンクをクリックすると、ブラウザのアドレスバーが
twitter.com
からamazon.co.jp
に切り替わり、Amazon の商品ページへ移動する。
- ユーザーが SNS(例:
- 例2.
- ユーザーがニュースサイト(例:
news.example.com
)を閲覧している。 - 記事内に YouTube 動画が埋め込まれており、
<iframe>
タグや<script>
タグを通じて youtube.com のリソースが読み込まれる。 - ブラウザは
news.example.com
からyoutube.com
に対して動画データやスクリプトの取得リクエストを自動的に送信する。
- ユーザーがニュースサイト(例:
対策方法
CSRFトークン ※ SSRの場合
- CSRFトークン
- リクエストが正規の画面から送られたかどうかを検証する、リクエストの「正当性」を確認するための使い捨ての値。
- サーバーがランダムな文字列(例:トークン)を発行し、フォームやリクエストに仕込ませる。
- リクエスト時にそのトークンが送られてきたら「このリクエストは正しい画面から送られた」とみなす。
- トークンがなかったり間違っていたら、リクエストを拒否する。
- Synchronizer Token Pattern
- CSRFトークンを使って、攻撃者や悪意ある第三者サイトからリクエストを送る(CSRF攻撃)を防ぐパターン。
AuthorizationヘッダーとCORS設定 ※ SPA + APIの場合
-
Authorization
ヘッダーにBearerトークン(またはセッションID)を載せる- Bearerトークン
- OAuth2の標準、OIDCにおける認証用のトークン。
- 中身としてJWTが使われる場合が多い。
Authorization: Bearer トークン
- Bearerトークン
- CORS(Cross-Origin Resource Sharing)
- 他のドメインから送信されたリクエストを、サーバー側で受け入れるか拒否するかを制御する、サーバー側の設定。
- 例えば、次のようにCORS設定を行うことで、APIサーバーで以下のことが達成できる。
- 許可されたオリジン(例: https://your-spa.example.com )から来たリクエストだけを受け入れる
- 許可したリクエストヘッダー(Authorizationなど)だけを許可する
- 実際にリクエストが行われた時、以下のように動作する。
- ブラウザがプリフライトリクエスト(OPTIONS)を送信する
OPTIONS /userinfo HTTP/1.1 Origin: https://your-spa.example.com # 送信元 Access-Control-Request-Method: GET # 本来送る予定のメソッド Access-Control-Request-Headers: Authorization, Content-Type # リクエストに使うカスタムヘッダ Host: api.example.com # 送信先
- APIサーバーがプリフライトリクエストに応答する
HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://your-spa.example.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Authorization, Content-Type Access-Control-Max-Age: 86400
- APIサーバーの設定が条件を満たす場合、ブラウザは本リクエスト(実際のAPIリクエスト)を送信する
GET /userinfo HTTP/1.1 Origin: https://your-spa.example.com Authorization: Bearer abcdefg12345 Content-Type: application/json Host: api.example.com
- APIサーバーの設定が条件を満たさない場合、ブラウザコンソールにエラーが出る
Access to fetch at 'https://api.example.com/userinfo' from origin 'https://your-spa.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
- ブラウザがプリフライトリクエスト(OPTIONS)を送信する
SameSite
属性
- サーバーは、ブラウザが クロスサイトリクエストを行うときに Cookie を送信するかどうか を制限することができる。
-
SameSite
属性は、以下の3つの値を指定できる。
Strict
Lax
None
注意: 最近の主要ブラウザ(Chrome、Edge、Firefox)では、SameSite
属性が明示されていない Cookie に、 Lax
をデフォルト適用する挙動になっている(2020年以降の仕様変更)。
ただし、古いブラウザや一部例外もあるため、明示的に設定することが推奨される。
SameSite=Strict
以下のようにサーバーのレスポンスヘッダーで設定したとき、
Set-Cookie: cart=110045_77895_53420; SameSite=Strict
- ブラウザは、同一サイトからリクエストを送信するときのみ、 Cookie を送信する。
- ログインセッションや支払い・カート情報など、常に同一サイト内でのみ利用される機密情報を送信するときに使用する。
- 例えば、ユーザーが銀行サイト (
bank.example.com
) へアクセスし、ログインフォームから認証を行うと、bank.example.com
のサーバーがSameSite=Strict
を指定したSet-Cookie
ヘッダーを返す。
これにより、ブラウザは同一サイト (bank.example.com
) でのみ、セッションIDを持つ Cookie を含めてリクエストを送信するようになり、認証状態が維持される。
仮に、ユーザーが攻撃者によって用意された別ドメイン(malicious-site.com
)上のリンクやフォームからbank.example.com
にリクエストを送信してしまっても、SameSite=Strict
設定のおかげでセッションIDsession_id
は送られないため、CSRF 攻撃を防ぎやすくなる。
注意: 機密情報に使用される Cookie の有効期間も短くする必要がある。
SameSite=Lax
以下のようにサーバーのレスポンスヘッダーで設定したとき、
Set-Cookie: affiliate=e4rt45dw; SameSite=Lax
- ブラウザは、トップレベルナビゲーション(サイトのアドレスバーのURLが切り替わるようなユーザー操作)では Cookie を送信する。
- ブラウザは、サブリクエスト(
fetch()
やXMLHttpRequest
、<iframe>
,<img>
,<script>
などの埋め込み要素によるリクエスト)では Cookie を送信しない。 - 例えば、Amazonのようなパートナーサイトでは、ユーザーが第三者の運営するアフィリエイトサイトからリンクを踏んでAmazonに流入してきたことが追跡できるように、クロスサイトである第三者の運営するアフィリエイトサイトからリクエストが送信されるときも、Amazonのサーバーが返却した Cookie を送信する必要がある。そのため、Amazon のサーバーでは
Set-Cookie
でSameSite=Lax
を設定する必要がある。
SameSite=None
以下のようにサーバーのレスポンスヘッダーで設定したとき、
Set-Cookie: widget_session=7yjgj57e4n3d; SameSite=None; Secure; HttpOnly
- ブラウザは、すべてのリクエスト(同一サイト / 異なるサイト問わず)で Cookie を送信する。
-
SameSite=None
が設定されている場合は、安全のため、Secure
属性も設定する必要がある。 - 例えば、広告サーバー(
ads.example.net
)では、ユーザーが第三者が運営するメディアサイト(例:news.example.com
)から広告となるスクリプトや画像を読み込んだことがわかるように、クロスサイトであるメディアサイトからリクエストが送信されるときも、広告サーバーが返却した Cookie を送信できる必要がある。そのため、広告サーバーではSet-Cookie
でSameSite=None
を設定する必要がある。
クッキーのプレフィックス
サーバーは Cookie がどこで設定されたかを判別できない
- Cookie の仕組み上、サーバーは、リクエストに含まれる Cookie が実際にどのドメインで設定(=
Set-Cookie
)されたかを確認することができない。 - 例えば、 サブドメイン(
foo.example.com
)が上位ドメイン(exapmle.com
)をDomain
属性に指定し、 Cookie を設定すると、exapmle.com
配下のすべてのサブドメイン(foo.example.com
,bar.example.com
,baz.example.com
, etc)でその Cookie を利用することができてしまう。 - 「セッション固定攻撃」のために悪用される可能性がある。
- 「多層防御 (Defense in Depth)」 として、Cookie 名に特定の接頭辞(プレフィックス)を付与することで「この Cookie は特定の条件を満たす Cookie である」ことをブラウザに宣言し、ブラウザ側で不正な Cookie 設定を防ぐ仕組みがある。
__Host-
と __Secure-
- Cookie 名の先頭に
__Host-
または__Secure-
を付けると、ブラウザは、それぞれ以下のような制約を満たさない限り、そのCookie
をブラウザに設定しないようになる。
__Host-
Cookie 名にこの接頭辞がついている場合、レスポンスの Set-Cookie
ヘッダーがブラウザで受信できるのは、以下の場合のみ。
-
Secure
属性が付与されている - リクエストが HTTPS 通信によって行われた
-
Domain
属性を指定していない -
Path
属性が/
になっている
これらをすべて満たす Cookie は、サブドメインや別パス経由で上書き・奪取されるリスクを低減することができる(= ドメインロック+パスルート強制)。
例えば、サブドメインで __Host-
プレフィックス付き Cookie を設定しようとしても、 Domain
属性を含んでいる場合などはブラウザ Set-Cookie
ヘッダーを受信しない。
__Secure-
Cookie 名にこの接頭辞がついている場合、レスポンスの Set-Cookie
ヘッダーがブラウザで受信できるのは、以下の場合のみ。
-
Secure
属性が付与されている - リクエストが HTTPS 通信によって行われた
__Host-
よりも要件は緩やかで、 Domain
や Path
の指定は許容される。
メモ:
Webアプリケーション側では、プレフィックスを含む完全な Cookie 名をそのままチェックする必要がある(User Agent によって、リクエスト送信前にプレフィックスが取り除かれるといったことはない)。
プライバシーとトラッキング
SameSite 属性の役割
- 先に書いたように、
SameSite
属性を使うと、クロスサイトリクエストの時に Cookie を送信するかどうかを制御できる。 - これは CSRF 攻撃の防止や、一部のトラッキングを抑止する上で役立つが、第三者ドメインによるクロスサイト追跡(サードパーティ Cookie)のすべてを防ぐわけではない。
サードパーティ Cookie とは
- 現在アクセスしているサイトとは異なるサイト(第三者のドメイン)によってブラウザに設定される Cookie のこと。
- 例えば、ユーザーが
news.example.com
を閲覧しており、そのページの中に、別ドメインの<iframe>
タグや広告や分析サービス(例:ads.provider.net
)のスクリプトや画像などが埋め込まれている場合、ブラウザがnews.example.com
からads.provider.net
へリクエストを行うと、レスポンスにSet-Cookie
ヘッダーが含まれる。こうして、「閲覧中のドメイン(news.example.com
)とは異なるドメイン(ads.provider.net
)」がブラウザに Cookie を設定するため、それがサードパーティ Cookie となる。
クロスサイトトラッキングとブラウザによる規制
- サードパーティ Cookie の使い方次第では、ユーザーに望まれない形で行動プロファイリングが行われるリスクがある。
- 例えば、「サイトA」で商品の情報を調べ、別の「サイトB」や「サイトC」に移動しても、同じ第三者ドメインが提供する広告ネットワークにより、「サイトA」の閲覧履歴を元に似た製品の広告が延々と表示される、ということがあり得る。
- ユーザーの閲覧行動が多数のサイトにわたって関連付けられるため、プライバシー面で問題視されることがある。
- 多くのブラウザーメーカーは、こうした クロスサイトトラッキング がユーザーに好まれないことを把握しており、以下のようにサードパーティ Cookie をブロックする動きを強めている。
-
デフォルトでブロック
- 一部のブラウザーでは、サードパーティ Cookie をデフォルト設定で完全にブロックする。
-
段階的なブロック
- 一部のブラウザーでは、サードパーティ Cookie を段階的に廃止・制限する方向へ進んでいる。
-
ユーザー設定や拡張機能によるブロック
- 一部のブラウザーでは、ユーザーが手動でサードパーティ Cookie をブロックしたり、トラッキング防止機能を有効化することができる。
-
デフォルトでブロック
- サードパーティ Cookie をブロックすると、以下のような影響が考えられるため、将来的にさらに厳しい制限が施されることを見据えて、サードパーティ Cookie に依存しない仕組みを検討する必要がある。
- ソーシャルメディアウィジェットや埋め込みコンテンツが正しく動作しなくなる場合がある。
- 広告や分析ツールが十分に機能しなくなる可能性がある。
Cookie に関する規制
- Webサイトでの Cookie の使用に関する法規制として、以下のようなものがある。
主な法規制
- 以下の規制は、それぞれの管轄区域(EU とカリフォルニア州)に居住するユーザーがアクセスするウェブサイトに適用され、グローバルに影響を及ぼす。
- The General Data Privacy Regulation (GDPR) in the European Union
- The ePrivacy Directive in the EU
-
The California Consumer Privacy Act(CCPA)
- 特に、カリフォルニア州の CCPA は、年間売上高が2,500万ドル以上の事業者に適用される。
規制の要件
- 上記の規制は、ユーザーのプライバシーを保護するために以下のような要件を設けている。
-
Cookie 使用の通知
- Webサイトは、Cookie の使用目的や種類をユーザーに対して明示的に通知する必要がある。
- 通知は分かりやすく表示され、ユーザーが容易にアクセスできる場所(例:バナー、ポップアップ)に配置されることが求められる。
-
ユーザーによる Cookie の管理
- ユーザーが一部またはすべての Cookie をオプトアウト(拒否)できるようにする必要がある。
- オプトアウトの方法は簡便で、ユーザーが容易に設定を変更できるインターフェースが提供されることが求められる。
-
サービスの利用性維持
- ユーザーが Cookie を拒否しても、Webサイトの主要な機能やサービスが利用可能であることを保証する必要がある。
- 必須でない Cookie を拒否した場合でも、ユーザーエクスペリエンスが著しく損なわれないよう配慮が求められる。
その他の地域の規制
- 地域によっては、上記以外にも Cookie の使用を管理する法規制が存在する。
- Lei Geral de Proteção de Dados(LGPD)※ ブラジル
- PIPEDA(Personal Information Protection and Electronic Documents Act)※ カナダ
- これらの規制も、対象となる地域のユーザーに対して Cookie の使用を適切に管理することを義務付けており、Webサイト運営者は、対象地域の法規制を理解し、遵守する責任がある。
規制遵守のための支援ツール
- 法規制を遵守するための「Cookie 同意管理」ツールや「Cookie バナー」を提供するサービスが多数存在する。
- これらのツールを利用することで、以下のような対応が容易になり、法規制遵守の負担を軽減し、ユーザーのプライバシー保護を強化することができる。
-
同意取得の自動化
- ユーザーからの同意を自動的に取得し、記録する機能。
-
Cookie の分類と管理
- 必須 Cookie、パフォーマンス Cookie、広告 Cookie など、種類ごとに管理・制御する機能。
-
ユーザー設定の保存
- ユーザーが選択した Cookie の設定を保存し、次回以降の訪問時に適用する機能。
-
同意取得の自動化