こんにちは。セキュリティの世界へようこそ。
日々、コードと向き合い、サービスを育てている皆さんに、今日は「セッション固定攻撃(Session Fixation)」という、少し地味だけれど非常に恐ろしい罠についてお話しします。
「認証を通せば安全」と思っていませんか?実は、家の鍵をどれだけ頑丈にしても、その鍵そのものを「泥棒が用意したもの」とすり替えられていたら、意味がありませんよね。
今日は、そんな「鍵のすり替え」を防ぐための、エンジニアとしての作法を紐解いていきましょう。
—
1. セッション固定攻撃って何?「泥棒のマスターキー」の話
Webサイトにログインすると、サーバーから「あなたは誰々さんですね」という証明書(セッションID)が発行されます。ブラウザはこのIDをクッキーという場所に保存し、ページを移動するたびに「私、ログイン中の〇〇です」とサーバーに見せに行くわけです。
セッション固定攻撃は、この流れを逆手に取ります。
1. 攻撃者の罠: まず、攻撃者がそのWebサイトにアクセスし、サーバーから自分用のセッションIDをもらいます。
2. 鍵の受け渡し: 攻撃者は、何らかの方法でそのIDを被害者のブラウザに「セット」させます。
3. 罠の発動: 被害者がそのIDを使ったままログインすると、サーバーは「お、このIDの人はログインに成功したな」と認識します。
4. 乗っ取り完了: サーバー側では「ログイン済みのセッション」として扱われていますが、実はそのIDは攻撃者が握っているもの。攻撃者は、被害者のふりをしてそのままサイトに潜り込めるのです。
要するに、「被害者がログインする前から、攻撃者が用意した鍵で部屋を開けられる状態にしておく」という、非常に巧妙な手口なんです。
—
2. 対策のゴールデンルール:「ログイン時に鍵を捨てて、新しく作る」
この攻撃を防ぐための唯一にして最大の対策。それは、「ログインが成功した瞬間に、古いセッションIDを捨てて、新しいIDを発行すること」です。
これを専門用語で「セッション再生成(Regenerate)」と呼びます。
実践:PHPでの実装例
PHPでセッションを扱う場合、ログイン成功時に以下のコードを入れるのが鉄則です。
たったこれだけの処理ですが、これで「ログイン前のID」という泥棒のマスターキーは無効化されます。ログイン成功という扉をくぐるたびに、常に新しい鍵に交換する。この習慣が、あなたのサービスを守る最強の防壁になるんです。
—
3. 防御の「もう一つの盾」:クッキー属性の設定
セッションIDを扱う際、ブラウザの設定(クッキー属性)を厳しくすることも重要です。特に以下の2つは、今の開発現場では「設定していて当たり前」の標準仕様です。
HTTPOnly属性
- 役割: JavaScriptからセッションIDを盗めなくします。
- なぜ?: 万が一、サイトにXSS(クロスサイトスクリプティング)という脆弱性があったとしても、JavaScriptからクッキーを読み取れなければ、攻撃者はIDを奪うことができません。
Secure属性
- 役割: 暗号化されたHTTPS通信でしかセッションIDを送らないようにします。
- なぜ?: 平文の通信(HTTP)だと、途中で通信を盗聴されてIDが漏れる可能性があります。
PHPでの設定例(php.ini または設定ファイル)
; クッキーをJavaScriptから読み取り不可にする
session.cookie_httponly = On
; HTTPS通信時のみクッキーを送るようにする
session.cookie_secure = On
; 外部サイトへのクッキー送信を制限する(CSRF対策にも有効)
session.cookie_samesite = “Lax”
—
最後に:セキュリティは「泥臭い積み重ね」です
セキュリティというと、何やら魔法のような技術や、複雑なファイアウォールを想像しがちです。でも、実際には今回紹介した「ログイン時に再生成する」「クッキーに正しい属性をつける」といった、当たり前のことを当たり前にやる積み重ねが、何よりも強固な守りになります。
もし今、あなたが開発しているサービスで「ログインしてもセッションIDが変わっていないな」と気づいたら、それは改善のチャンスです。
今日から一歩ずつ、セキュアな設計をコードに落とし込んでいきましょう。あなたの書いたその一行が、ユーザーの大切な情報を守る「盾」になるのですから。
また次の記事で、より深い現場の知見を共有しますね。一緒に最高のものを作っていきましょう!
コメント