最終更新
リンドくん
たなべ先生、Webアプリを作っていて「ログイン状態を保つ」って仕組みがよくわからないんです。どうやってサーバは「この人はログイン済み」って覚えているんですか?
たなべ
それがセッション管理という仕組みなんだ。
RPGで例えると、冒険者が宿屋で「宿帳に名前を書いて部屋の鍵をもらう」みたいなイメージかな。その鍵がクッキーなんだよ。
リンドくん
なるほど!でも、その鍵を悪い人に盗まれたら大変ですよね?
たなべ
まさにそこが重要なポイント!だからクッキーには特別な鍵のかけ方があるんだ。
今日は、Webセキュリティの基本となる「セッション管理」と「クッキー属性」について、初心者の方にもわかりやすく解説していくよ。
Webアプリケーション開発を学び始めると、必ず直面するのがログイン機能の実装です。
「ユーザーがログインした状態を保つ」という、一見当たり前に思える機能ですが、その裏側ではセッション管理という重要な仕組みが働いています。
しかし、この仕組みを正しく理解せずに実装すると、深刻なセキュリティの脆弱性を生んでしまう可能性があります。
実際、不適切なセッション管理は、情報漏洩やアカウント乗っ取りといった重大な被害につながるケースが後を絶ちません。
本記事では、Webセキュリティの基礎となるセッション管理の仕組みと、それを守るためのクッキー属性(Secure・HttpOnly・SameSite)について、プログラミング初心者の方でも理解できるよう、段階的に解説していきます。
HackATAは、エンジニアを目指す方のためのプログラミング学習コーチングサービスです。 経験豊富な現役エンジニアがあなたの学習をサポートします。
✓ 質問し放題
✓ β版公開中(2025年内の特別割引)
リンドくん
そもそもセッション管理って、なぜ必要なんですか?
たなべ
実はHTTPという通信の仕組み自体が「誰が通信しているか覚えていない」んだ。
だから、ログイン状態を保つには特別な工夫が必要なんだよ。
Webの基本となるHTTP通信には、重要な特徴があります。それはステートレス(状態を持たない)という性質です。
これはどういうことかというと、HTTPでは一つ一つのリクエストが独立しているため、サーバは「さっきアクセスしてきた人と、今アクセスしてきた人が同じ人かどうか」を判別できないのです。
RPGで例えるなら、こんな感じです。
Webの世界では、このままだとログイン機能が実装できません。ログインしても、次のページに移動した瞬間に「あなたは誰ですか?」と聞かれてしまうからです。
この問題を解決するのがセッション管理です。具体的な流れを見ていきましょう。
1. ログイン時の処理
2. ログイン後のアクセス
このように、セッションIDという「通行手形」をやり取りすることで、サーバはユーザーを識別できるようになるのです。
セッション管理で登場した「クッキー」について、もう少し詳しく見てみましょう。
クッキー(Cookie)とは、Webサイトがブラウザに保存する小さなデータです。
ブラウザは、同じWebサイトにアクセスする際、自動的にこのクッキーをサーバに送信します。
RPGで例えると、以下のようなイメージです。
実際のクッキーの例を見てみましょう。
この1行の中に、セッションIDだけでなく、セキュリティのための重要な設定がたくさん含まれています。これらが、今回のテーマであるクッキー属性なのです。
リンドくん
クッキーに保存されているセッションIDが盗まれたら、どうなるんですか?
たなべ
それが大問題なんだ!セッションIDを盗まれると、攻撃者があなたになりすましてログインできてしまうんだよ。
これをセッションハイジャックと呼ぶんだ。
セッションIDが盗まれると、以下のような被害が発生する可能性があります。
RPGで例えると、「宿屋の鍵を盗まれて、あなたの部屋に勝手に入られる」ようなものです。
クッキー(セッションID)を盗む攻撃には、主に以下のようなものがあります。
悪意のあるJavaScriptをWebページに埋め込み、クッキーを盗み出す攻撃です。
通信経路上でデータを盗聴し、クッキーを入手する攻撃です。特に暗号化されていない通信(HTTP)では危険性が高まります。
ユーザーが意図しない操作を、攻撃者が仕掛けたWebページ経由で実行させる攻撃です。
これらの攻撃から守るために、クッキーにはセキュリティ属性を設定することができます。それが以下の3つです。
これらの属性を適切に設定することが、セキュアなWebアプリケーション開発の基本となります。次のセクションから、それぞれの属性について詳しく見ていきましょう。
リンドくん
Secure属性って、何を「セキュア」にしてくれるんですか?
たなべ
簡単に言うと、「暗号化されていない通信では絶対にクッキーを送らない」という設定なんだ。
これで盗聴のリスクをグッと減らせるよ。
まず、通信プロトコルの違いを理解しましょう。
HTTP通信では、データが平文(誰でも読める状態)でインターネット上を流れます。これは、カフェの無料Wi-Fiなどで通信している場合、同じネットワーク上にいる人がデータを盗聴できてしまうことを意味します。
Secure属性を設定すると、そのクッキーはHTTPS通信でのみサーバに送信されるようになります。
この設定により、以下のような保護が実現されます。
保護されるケース
保護されないケース
主要なプログラミング言語でのSecure属性の設定方法を見てみましょう。
Python(Flask)の例
Node.js(Express)の例
PHPの例
Secure属性を使用する際の注意点は以下の通りです。
Secure属性は、通信経路での盗聴から守る基本的な防御策です。現代のWebアプリケーションでは、必ず設定すべき属性と言えるでしょう。
リンドくん
HttpOnly属性は何を防いでくれるんですか?
たなべ
これはXSS攻撃からクッキーを守るための属性なんだ。
JavaScriptからdocument.cookieでクッキーを読み取れなくするんだよ。
XSS(クロスサイトスクリプティング)攻撃では、攻撃者が悪意のあるJavaScriptをWebページに埋め込みます。
攻撃例
このスクリプトが実行されると、そのページに設定されているすべてのクッキー(セッションIDを含む)が盗まれてしまいます。
HttpOnly属性を設定すると、そのクッキーはJavaScriptからアクセスできなくなります。
この設定により、以下のような保護が実現されます。
HttpOnlyなしの場合
HttpOnlyありの場合
HttpOnly属性が設定されたクッキーは、以下のような特性を持ちます。
document.cookieで読み取れないRPGで例えると、「宿屋の鍵は持っているけど、盗賊(悪意のあるスクリプト)には見えない魔法がかかっている」ようなイメージです。
HttpOnly属性を使用する際のポイントは以下の通りです。
すべてのセッションクッキーに設定する
APIトークンにも適用を検討する
JavaScriptからアクセスする必要がないトークンには、HttpOnly属性を設定しましょう。
XSS対策は多層防御が基本
HttpOnly属性だけでなく、以下の対策も併せて実施することが重要です。
HttpOnly属性は、XSS攻撃によるクッキー窃取を防ぐ最後の砦です。セッション管理においては、必ず設定すべき属性と言えるでしょう。
リンドくん
SameSite属性って、他の2つと比べると複雑そうですね...
たなべ
確かに少し複雑だけど、「他のサイトからのリクエストにクッキーを含めるかどうか」を制御する属性なんだ。
これでCSRF攻撃を防げるんだよ。
CSRF(Cross-Site Request Forgery: クロスサイトリクエストフォージェリ)攻撃は、ユーザーが意図しない操作を勝手に実行させる攻撃です。
攻撃シナリオの例
この攻撃の怖いところは、ユーザーが何もクリックしなくても、ページを開いただけで実行されてしまう点です。
SameSite属性には、3つの設定値があります。それぞれの挙動を見ていきましょう。
動作例
メリット: CSRF攻撃を完全に防げる
デメリット: 外部サイトからのリンク経由でアクセスした場合、ログアウト状態になる
動作例
メリット: CSRF攻撃を防ぎつつ、ユーザビリティも確保
デメリット: GETリクエストでの攻撃には無防備(ただしGETで状態変更すべきではない)
動作例
用途: サードパーティクッキーが必要な場合(広告、埋め込みコンテンツなど)
注意: CSRF攻撃のリスクがあるため、別の対策が必要
現代のWebアプリケーションでは、以下の設定が推奨されます。
一般的なWebアプリケーション
より高いセキュリティが必要な場合(銀行系など)
重要な点として、2020年以降の主要ブラウザは、SameSite属性が未指定の場合、自動的にLaxとして扱います。これは、CSRF攻撃のリスクを減らすための措置です。
ただし、明示的に設定することで以下のメリットがあります。
SameSite属性は、CSRF攻撃に対する強力な防御策であり、Secure・HttpOnlyと併せて設定することで、セキュアなセッション管理が実現できます。
リンドくん
3つの属性の役割がよく分かりました!でも、全部同時に使うんですよね?
たなべ
その通り!この3つの属性は、それぞれ異なる攻撃から守ってくれるんだ。
どれか1つだけではなく、すべて設定することが現代のセキュリティの基本だよ。
セッション管理とクッキー属性について、ここまで詳しく見てきました。
最後に、重要なポイントをまとめておきましょう。
| 属性 | 防ぐ攻撃 | 役割 |
|---|---|---|
| Secure | 中間者攻撃(盗聴) | HTTPS通信でのみクッキーを送信 |
| HttpOnly | XSS攻撃 | JavaScriptからクッキーを読み取れなくする |
| SameSite | CSRF攻撃 | 他サイトからのリクエストにクッキーを含めない |
これらはそれぞれ異なる脅威に対応しているため、すべて同時に設定することが重要です。
Webセキュリティは奥深く、学ぶべきことは多いですが、今日学んだセッション管理とクッキー属性は、その基礎となる非常に重要な知識です。
セキュリティは、後から付け足すものではなく、設計段階から組み込むべきものです。
今回学んだクッキー属性の適切な設定は、その第一歩となります。
プログラミング初心者の方も、これからWebアプリケーションを開発する際は、ぜひ今日学んだ内容を実践してみてください。
セキュリティを意識した開発は、ユーザーの信頼を守ることにつながります。