インターネットの「クッキー」とは
筆者は、Webを見ていてもブログを書いていてもクッキーの存在をあまり意識したことがなかったのですが、縁の下の力持ちとしてEコマースサイトで活躍しているだけでなく、プライバシーを気にする際にも重要な存在のようです。
Google Chromeが2020年2月にクッキーのSameSite属性のデフォルト値を変えるという話を見つけたのをきっかけに、そんなに重大なことなのだろうかと思い、クッキーについての理解を深めようと調べました。
クッキーとは何かを改めて
クッキー(cookie)とはWebサーバとブラウザの状態を管理するプロトコルの名前で、保存用に使われているファイルを指すこともあります。
クッキーはウェブサーバがHTTPヘッダと一緒にブラウザに渡されブラウザ側のローカル領域に一時保存されます。次に同じWebサーバと通信する際、ブラウザはHTTPヘッダと共にクッキーのデータをサーバに送りその状態をサーバに知らせます。サーバはそれを受け取り、更新されたクッキーをまたブラウザに渡します。
どのドメインで使うかという範囲制限と、いつまで、たとえば10秒後だったり、1か月後だったりという期限があります。これらは次に説明する属性にセットします。
データは、キーとバリューの組で保持され、そこへオプションとしていくつかの属性をセットできます。
クッキーの属性の種類
クッキーには次のような属性があります。これらの情報はMDN:「HTTP Cookie の使用」に詳しく書かれています。
- domain
使用できるドメインを設定します。ドメイン毎にクッキーが存在し異なるサイトのクッキーは送信されません。例えばdomain.comとだけ設定すると、「www.domain.com」や「blog.domain.com」で利用が可能になります。この場合blog.domain.comにおいてセキュリティの脆弱性があった場合、www.domain.comにも影響するということにもなります。そうしたくない場合はサブドメインまで含める形で設定します。
- path
ドメインだけでなくクッキーが有効なパスも設定できます。仮にPathを/abcとした場合、/abcにアクセスした場合に加え、/abc/defや/abc/def/ghiなどにアクセスした場合にも送信されます。
- expire
使用期限を日時で設定します。2038年問題の影響を受けて32ビット機だと2038年以降の日付だとクッキーが保存されません(設定後すぐに削除されてしまいます)。確認はしていませんが64ビット機では9999年まで指定できるそうです。
また、期限を設定する属性としてmax-ageというものも存在します。これは秒数で指定するものでexpireと同時に使うと、max-ageが採用されます。
- secure
ひと昔前の情報セキュリティ試験の時によく出ました(今も?)、https接続の時のみクッキーを有効にするものです。http接続時に送信してしまうと、クッキーの中身を盗聴されてしまう可能性があります。
Google ChromeのVer80以降からはSecure属性がついていないクッキーは読み取りができないようになるそうです。
- httponly
JavaScriptからクッキーを参照するのを禁止します。悪意のあるJavaScriptによりクッキーを操作されないようにする目的で利用されます。
- samesite
もともとクッキーは異なるドメインには送信しませんが、表示中のページとは違うドメインのクッキーを送受信することがあります。それはimgやscriptタグから外部のサーバにある画像やスクリプトを受信する場合です。
この種のクッキーを「サードパーティークッキー」といいます。
なにが問題かというと、この機能の利用してウェブ閲覧者の動向を追うことができるからです。例えばAというサイトのクッキーが、B、C、Dのサイトを閲覧した時にも送受信される仕組みになっていれば、Aのサイトの管理者はリファラーと自分のクッキーに保存したIDから、IDを持つ人間がB、C、Dのサイトをいつ訪れたのかを知ることができます。
これを抑制するための属性で、サイトをまたがったクッキーの送受信を制限します。
設定値として禁止しない「samesite=none」、完全に禁止する「samesite=strict」、その中間の「samesite=lax」があります。
JavaScriptからクッキーを操作する
JavaScriptからクッキーを保存するには、document.cookieに対して値を代入します。
キーとバリューのセットに対して、属性を記載しそれぞれは;によって区切られます。値として、空白文字や;は入れられません。必要な場合はencodeURIComponent()関数で変換してセットします。
取得時は複数取得されるので、split関数等で分割します。
先のhttponly属性がついていたら、JavaScriptからの操作はできません。
参考にさせていただいたサイトです。ありがとうございました。