PR 本記事には広告(Amazonアソシエイト・もしもアフィリエイト・A8.net等)が含まれます。掲載情報の正確性には努めていますが、商品の詳細は必ずリンク先で最新情報をご確認ください。
CTF・セキュリティ学習

【セッション・Cookie編】奪われたら全部終わる身分証の守り方|CTF思考フレームワーク #08

かも次郎とアンペンが「セッション・Cookie」を解説するマスコットイラスト
安全に生きたい編集部

こんにちは、アンペンです!

前回は、プロフィール編集におけるIDOR・マスアサインメント・保存型XSSの話をしました。

今回は、ログイン後の通信を成立させている見えない仕組み、セッションとCookieを見ていきます。「身分証」のような役割を持つこの仕組みは、奪われた瞬間に全部終わってしまうほど重要な存在です。

Cookieってよく見るけど、なんでそんなに大事なの?

ログイン後の通信は、毎回ID/パスワードを送らずに『Cookieにある身分証』で本人確認してるんだ。身分証ごと盗まれると、本人としてログインしっぱなしの状態になっちゃう。

Webサイトを開くと出てくる『Cookieを許可しますか?』のポップアップ、なんとなくOKを押している人も多いですよね。あのCookie、実はログイン中のあなたにとって“身分証”そのものなんです。今日は「なぜCookieやセッションIDがそんなに大事なのか」「盗まれるとどうなるのか」を、ホテルのルームキーにたとえながら見ていきます。地味だけど、Webセキュリティのいちばんの土台になる話です。

まず結論

セッションIDを保持するCookieは、ログイン中の身分証そのものです。HttpOnly・Secure・SameSiteの3属性と、ログイン時の再発行・ログアウト時の破棄を整えないと、盗まれた瞬間に乗っ取られます。

この記事で分かること

  • セッションとCookieの関係(身分証としての役割)
  • セッションIDが盗まれる3つの代表的な経路
  • Cookieの安全な属性設定と運用ルール
難易度:はじめて向け 所要時間:10分 体験:Cookieの中身を観察する おすすめ:#07の後

📖 はじめてのWebセキュリティ #08|セッション・Cookie編
ログイン中の通信を支える「身分証」を題材に、奪われない設計と運用を学びます。 シリーズ一覧を見る →

⚠️ 大事なお約束
この記事の確認は、CTF・公式ラボ・自分で作った検証環境だけで行ってください。他人のCookieを取得する、共有端末からCookieを取り出す、といった行為は不正アクセス等に該当する可能性があります。

セッションとCookie:ログイン後の通信を支える仕組み

HTTP通信は本来「1回ごとに切れる」性質を持っています。それでもログイン状態を保てるのは、サーバーが利用者にセッションIDを発行し、ブラウザがそれをCookieとして毎回送り返しているからです。

つまり、ログイン中の通信は「ID/パスワードを毎回送る」のではなく「セッションIDという身分証だけを毎回見せる」形で動いています。

ここで一つ、意外な事実から。Web通信(HTTP)はもともと『毎回はじめまして』の仕組みなんです。ページを開くたびにサーバーとの会話はいったんリセットされ、サーバーは“さっきの人”を覚えていません。それでもログイン状態が続くのは、ブラウザが毎回こっそり“身分証”を見せ続けているから。その身分証の正体が、Cookieに入ったセッションIDなんです。

図解:本人のCookieと盗まれたCookie

本人と攻撃者が同じセッションIDのCookieを送り、サーバーが区別できない様子を示した比較図
同じセッションIDなら、誰が送っても本人として扱われる。Cookieは身分証そのもの。

正規の利用者が送るCookieと、攻撃者が手に入れたCookieは、サーバーから見れば同じ「身分証」です。サーバーは中身が同じであれば、誰が送っても受け入れてしまいます。

ここがセッションの“こわさ”の核心です。サーバーは身分証(セッションID)の中身しか見ていません。だから、それを差し出したのが本物の持ち主なのか、たまたま拾った第三者なのかを、区別できないんです。顔写真のない、番号だけの入館証——それをかざせば誰でも通れてしまう。だからこの番号は、何があっても他人の手に渡してはいけないわけです。

ホテルでルームキーを渡される利用者と、落ちたキーを拾う第三者のたとえ図
ルームキーを持っているだけで部屋に入れる仕組みは、Cookieと同じ性質を持つ。
🏨 たとえるなら、ホテルのルームキー

ホテルでチェックインすると、ルームキーが渡されます。フロントは毎回身分証を確認するわけではなく、「ルームキーを持っている人=その部屋の客」として扱います。もしルームキーが落ちていたら、拾った人もその部屋に入れてしまいます。Cookieも同じで、持っているだけで本人扱いされる性質を持ちます。

ここで覚える用語:セッションID
サーバーが利用者に発行する、長くてランダムな文字列です。Cookieとしてブラウザに保存され、リクエストのたびに自動で送信されます。これが本人確認の代わりになるため、漏れない・推測できないことが何より大切です。

『なぜそんなに長くてランダムなの?』と思うかもしれません。理由はシンプルで、短かったり規則的だったりすると、#03のリセットトークンと同じで“他人に当てられてしまう”からです。セッションIDは、誰にも推測できないほど長く・でたらめであるほど安全。逆に言えば、ここが短いだけで、わざわざ盗まなくても“宝くじを当てるように”乗っ取られる隙が生まれてしまいます。

セッションIDが盗まれる3つの経路

セッションIDが奪われる経路は、大きく3つです。『画面の罠(XSS)から盗む』『暗号化していない通信から盗み見る』『あらかじめ用意したIDを使わせる(セッション固定)』。1つ目と2つ目は“盗む”話、3つ目だけは少し毛色が違って“すり替える”話です。順番に見ていきましょう。

代表的な漏洩・乗っ取り経路

XSS経由・HTTPS未使用・セッション固定の3つの代表的なセッションID漏洩経路を示したインフォグラフィック
①XSS経由 ②HTTPS未使用 ③セッション固定。基本防具はHttpOnly/Secure/SameSiteの3属性。
  • XSS経由でJavaScriptから盗む:HttpOnlyが付いていないCookieは、ページ上のスクリプトから読めるため、XSSと組み合わさると一発で外部に送信できる
  • HTTPS未使用時の盗聴:暗号化されていない通信(HTTP)を流れるCookieは、同じネットワーク上で盗み見られる
  • セッション固定(セッションフィクセーション):攻撃者があらかじめ用意したセッションIDを利用者に使わせ、ログイン後にそのIDで成り済ます

これらは、Cookie側の属性設定と、ログイン時のセッションID再発行ルールで、ほとんど塞ぐことができます。

3つ目の『セッション固定』は、初めて聞くとちょっと不思議な手口です。普通は“ログインした人のIDを盗む”のに、これは逆。攻撃者が先に自分で用意したセッションIDを、何らかの方法で利用者に“使わせて”おくんです。そして利用者がそのIDのままログインすると、攻撃者は最初から知っているIDで、すんなり本人になりすませてしまう。だから守る側は『ログインが成功した瞬間にIDを作り直す』——たったこれだけで、この手口はピシャリと防げます。

ここから自分のブラウザでCookieを観察してみましょう。といっても、難しい操作はいりません。開発者ツールを開いて“自分の身分証”を眺めるだけです。注意点はただ一つ、他人の端末や他人のCookieには絶対に手を出さないこと。自分のセッションがどんな鎧を着ているかを知るだけで、十分に学びになります。

CTFでやってみよう:Cookieの中身と属性を観察する

やってみよう / 演習環境限定

自分の演習環境で、Cookieの中身と属性を確認しよう

目的は他人のCookieを取ることではなく、「自分のセッションがどんな属性で守られているか」を見ることです。

  1. CTFや自分の検証環境にログインする
  2. ブラウザの開発者ツールでアプリケーション(Storage)タブを開き、Cookieを確認する
  3. セッションIDの名前と長さ、ランダム性をメモする
  4. 属性欄(HttpOnly / Secure / SameSite / 有効期限)がどう設定されているか確認する
  5. 一度ログアウトし、再度ログインしたときにセッションIDが変わるかを観察する
他人の端末・他人のCookieを取り出して試すのは絶対にやめてください。確認は「自分のブラウザの、自分のセッション」の範囲だけで十分です。

守りの中心になるのが、Cookieに付ける3つの“属性”です。名前だけ聞くと暗号みたいですが、やっていることはとてもシンプル。次の会話でイメージをつかみましょう。

HttpOnly、Secure、SameSite…呪文みたいで覚えられないよ。

大丈夫、役割で覚えればいいよ。HttpOnly は『JavaScriptに身分証を触らせない』——XSSで盗まれるのを防ぐ鍵。Secure は『暗号化された道(HTTPS)でしか身分証を持ち出さない』——盗み見を防ぐ鍵。SameSite は『よその家から勝手に使わせない』——なりすまし送信を防ぐ鍵。この3つで“見せない・漏らさない・悪用させない”をカバーするんだ。

守る側なら、Cookie属性と再発行ルールを徹底しよう

Cookieを守る基本は、3つの属性(HttpOnly・Secure・SameSite)を必ずセットすることと、ログインのたびにセッションIDを更新することです。

守るための基本チェック
  • セッションIDの入っているCookieにはHttpOnlyを付け、JavaScriptから読めなくする
  • Secure属性を付け、HTTPS通信のときだけCookieを送るようにする
  • SameSite属性をLaxまたはStrictにし、外部サイトからの自動送信を抑える
  • ログイン成功時・権限変更時にはセッションIDを必ず再発行する
  • ログアウト時はサーバー側でセッションを破棄し、Cookieも無効化する
  • 一定時間操作がない場合に自動でセッションを切る仕組みを入れる
  • サイト全体をHTTPSに統一(HSTSも有効化)し、Cookieが平文で流れる経路をなくす

Cookieの『属性3点セット』はWebサイトの基礎防具なんだね。

そう。HttpOnly・Secure・SameSiteの3点を揃えてから他の対策に進むと、土台がしっかりするよ。

ここまでをひと言で言うと、セッションIDは『落としてはいけない、顔写真のない合鍵』です。だから守りは、“盗まれない工夫”と“万一盗まれても使い続けられない工夫”の二本立てになります。属性3点セットが前者、ログイン時の再発行やログアウト破棄が後者、というわけですね。両方そろって、はじめて身分証はしっかり守られます。

まとめ:セッションIDは「身分証そのもの」

今回のポイント
  • セッションIDはログイン中の身分証で、奪われれば本人として動かれる
  • 漏洩経路は主にXSS・HTTPS未使用・セッション固定の3つ
  • HttpOnly・Secure・SameSiteの3属性が基本防具
  • ログイン時・権限変更時のセッションID再発行を忘れない

今日の持ち帰りは『セッションIDは身分証。見せない・短命に・作り直す』です。HttpOnly/Secure/SameSiteで盗まれにくくし、ログインのたびに作り直し、ログアウトでしっかり捨てる。この当たり前を徹底するだけで、乗っ取りの大半は防げます。派手さはありませんが、ここがガタつくと他のどんな対策も土台ごと崩れてしまう——いちばん大事な基礎なんです。

次回は、画面ではなくサーバー側プログラムが直接相手にするAPI・GraphQLを扱います。エンドポイント列挙とBOLAの世界を覗いていきましょう。

次に読みたい記事

参考資料

記事URLをコピーしました