今回の想定読者
今回のネタは、Cookieについてです。本記事を読んでいただけると、Cookieの基本的な役割や機能、Cookieを利用したサイトへの攻撃について、外観を掴むのに役立つと思います。
以下の様な方が想定読者です。
- Cookieって何気なく使っているけど、どんなものか理解が曖昧なので外観を掴みたい
- 普段は機能実装しかしてなくて、ログイン周りはノータッチなので理解を深めたい
ログビーの勉強会について
ログビー(Logbii)では、月一回オンラインの社内勉強会をしています。直近のものと、2025年以降のアーカイブを順次公開していきます。
ざっくりと、以下のルールで運用をしています。
- 月イチで、ランチタイムにオンライン開催(1時間)
- テーマ自由
- 持ち回りで開催
- ランチ代支給(2000円まで)、飲食可
- 業務時間扱いでOK(業務時間を削る形でよい)
今回の勉強会について
今回は、2025年2月の勉強会アーカイブです。
SwiftエンジニアのIshikuraさんが発表しました!
それでは、以下本編です。
Cookie
Cookieをテーマに選んだきっかけ
- 前職でWebViewを用いたアプリの対応を行っており、そこでCookieなどのWebの仕様について調べる機会があったため
- 普段Cookieを使用しているが個人的にあやふやな理解があるなと感じたため
- 勉強会に参加してくださる人にも少しは関係しているようなテーマ
Cookieについて
Cookieとは
ウェブサイトがユーザーのブラウザに保存する小さなデータファイル
Cookieの役割
- ユーザーの利便性向上
- ログイン情報の保持
- 一度ログインすると、次回訪問時もログイン状態を維持できる
- 設定の記憶
- ユーザーの選んだ言語やテーマを保存し、再訪問時も適用される
- ログイン情報の保持
- ユーザーの行動の分析、マーケティング
- 広告の最適化
- ユーザーの閲覧履歴をもとに、興味の有りそうな広告を表示
- 広告の最適化
Cookieの仕様、
Set-Cookie: name=value; Expires=Wed, 21 Oct 2025 07:28:00 GMT; Path=/; Domain=example.com; Secure; HttpOnly; SameSite=Lax
-
キーとバリュー
name=value- Cookieのキーと値
-
Expires属性
Expires=Wed, 21 Oct 2025 07:28:00 GMT- Cookieの有効期限を指定する
- このフォーマットはRFC 1123 で定義されている
- https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1
-
Max-Age属性
- 秒数指定
Max-Age=3600- Max-Age属性、Expires属性が両方与えられている場合はMax-Age属性が優先される
- 両方与えられていない場合はセッションCookieとなり、ブラウザが閉じるとCookieが削除される
ブラウザが閉じられるとセッションCookieが削除されるが、ブラウザによってはセッションCookieの復元機能を持っていることがあり、次回起動時にセッションCookieが復元されることがある。
Chromeの場合:設定→起動時→前回開いていたページを開く
-
Path属性
Path=/- Cookieが適用されるURLパスを指定するもの
- Pathを指定しない場合、Cookieがセットされたページのディレクトリを基準に動作する
-
Path=/- サイト全体で有効
-
Path=/user- 特定のパス以下で有効
- 例
Set-Cookie: user_id=12345; Path=/app;- 送信されるリクエスト
- 送信されないリクエスト
-
Domain属性
Domain=example.com- どのドメインでCookieを送信するか指定するもの
- Domain属性にトップレベルドメインのみを指定することはできない
- ❌️:
Domain=com/Domain=jp
- ❌️:
- 例
- Domain属性の値が
example.comならばexample.com/www.example.com/www.corp.example.comに送信することになる
- Domain属性の値が
- Domain属性の活用例
- サブドメイン間でのログイン共有
- Domain属性のセキュリティリスクなど
-
Domain=example.comを設定すると、support.example.com/dev.example.comでもCookieを使用できるため、想定外のCookieが共有されてしまう可能性がある - 対策
- 必要な範囲にのみDomain属性を適用する(
Domain=www.example.comなど) - 機密情報のCookieはSecure属性やHttpOnlyを併用する
- 必要な範囲にのみDomain属性を適用する(
-
-
Secure属性
Secure- CookieをHTTPS通信でのみ送信するようにする
- メリット
- HTTPでの盗聴を防ぐ
- HTTPのみの場合、Cookieは盗聴される可能性がある
- 中間者攻撃を防ぐ
- HTTP通信は簡単に改ざんできるため、悪意のある攻撃者がセッション情報を乗っ取る可能性がある
- HTTPでの盗聴を防ぐ
-
HttpOnly属性
HttpOnly- JavaScript(document.cookie)からCookieを取得できなくするための属性
-
HttpOnlyという名前だが、「HTTPSのときは送らない」という意味ではない - 良い点
- HttpOnly属性を設定するとXSS攻撃を防げる
- JavaScriptからCookieを取得できなくなるため、攻撃者がスクリプトを仕込んでもCookieを盗むことができなくなる
- HttpOnly属性を設定するとXSS攻撃を防げる
- 注意点
- 認証系のCookieにはHttpOnlyを推奨
- JavaScriptでCookieを操作する必要がある場合
- フロントエンドでCookieを使って認証を管理する場合
- アプリのネイティブでWebViewのスクリプトでCookie情報を取得するときなど
- フロントエンドでCookieを使って認証を管理する場合
-
SameSite属性
SameSite=Lax- Cookieがクロスサイト(異なるドメイン間)のリクエストで送信されるかどうかを制御するための属性
- 主にCSRF(クロスサイトリクエストフォージェリ)攻撃を防ぐ
- 設定できる種類
-
Strict:一切送信されない- 最も厳格な設定
- 同じサイト内のリクエストのみCookieを送信する
- クロスサイトのリクエストではCookieを送信しない
- 例
-
https://example.com→https://example.com/profile:送信される -
https://another.com→https://example.com:送信されない
-
- メリット
- CSRF攻撃を完全に防げる
- ユーザーのセッションが外部サイトから利用されるリスクがない
- デメリット
- ログイン中のページに対して、別のドメインから遷移し直すと未ログイン扱いになる
-
Lax:一部のケースで送信される- 同じサイト内のリクエストでは常にCookieを送信する
- GETリクエストのみクロスサイトでCookieを送信する
- POST / PUT / DELETE などのリクエストではCookieを送信しない
- 例
-
https://example.com→https://example.com/profile:送信される -
https://another.com→https://example.com(リンククリック):送信される -
https://another.com→https://example.com(フォーム送信):送信されない
-
-
None:常に送信される- すべてのリクエストでCookieを送信する
- Secure属性が必須(HTTPS のみ)
- 例
-
https://example.com→https://example.com/profile:送信される -
https://another.com→https://example.com:送信される
-
-
Cookieを用いた攻撃について
- 攻撃手法
- XSS(クロスサイトスクリプティング)
- JavaScriptを埋め込んで
document.cookieを実行し盗み、攻撃者に送信 - 悪意のあるJavaScriptを埋め込んで、被害者のブラウザで実行させCookieを盗み出す
- 種類
- Reflected XSS(反射型)
- Stored / Persistent XSS(格納型)
- DOM Based XSS
- 例
- セッションハイジャック
- 仮想通貨マイニング
- ページ改ざん
- Cookie観点からの対策
- HttpOnly属性を設定
- 事例
- YouTube
- KADOKAWAのHP改ざん
- ECサイトでの不正アクセスや個人情報の窃盗
- JavaScriptを埋め込んで
- CSRF(クロスサイトリクエストフォージェリ)
- 被害者が意図しないリクエストを送るように仕向け、攻撃者が利益を得る攻撃
- 被害者の認証済みセッションを悪用して、勝手に操作を行う
- 例
- 登録情報やパスワードが勝手に変更される
- 口座から不正に送金される
- 悪意のある投稿や犯罪予告をされる
- Cookie観点からの対策
- SameSite属性の設定
- 根本的な対策
- CSRFトークンの発行
- Refererの検証
- 事例
- XSS(クロスサイトスクリプティング)
ディスカッション
- Expire、Max-ageの有効期限の更新(satou)
- EnbrewのCookieなどの対策(kawahara)
- 現状、ローカルストレージに保存されている
- やるならReact側で対応する
- アプリケーションを開発するのであれば、セキュリティなどの部分を知識として入れとくと良い(matsuda)
- 勉強会のテーマについて
- iOSエンジニア目線どのようなテーマにすれば良いか少し難しい所があった
- 面白い、興味の入口になってくれれば一つのゴールになる(kawakubo)
- 一つとして実際に手を動かして試してみる
- 面白い、興味の入口になってくれれば一つのゴールになる(kawakubo)
- iOSエンジニア目線どのようなテーマにすれば良いか少し難しい所があった
参考記事
- https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies
- https://triple-underscore.github.io/http-cookie-ja.html#overview
- https://datatracker.ietf.org/doc/html/rfc6265
- https://www.tohoho-web.com/ex/cookie.html
- https://www.gmo.jp/security/cybersecurity/cyberattack/blog/csrf/
- https://hnavi.co.jp/knowledge/blog/cross-site-scripting/