こんにちは。セキュリティの世界へようこそ。
現場で泥臭いインシデント対応をしていると、「なぜこんな面倒な設定が必要なんだ?」とイライラする場面に遭遇することもあるでしょう。ですが、その「面倒」こそが、あなたのサービスを守る最後の砦だったりします。
今回は、Web開発の現場で必ず耳にするのに、意外と「なんとなく」で済ませられがちな「SameSite=None と Secure属性」という、最強のタッグについて紐解いていきましょう。
—
1. 「クッキー」はあなたの家の「合鍵」です
まずは、身近な例えから始めましょう。Webサイトにおける「クッキー(Cookie)」は、あなたがお客さんとしてサイトにログインした時に渡される「合鍵」のようなものです。
一度ログインすると、ブラウザが勝手にこの合鍵を使って「この人はさっきログインした本人ですよ」と証明してくれます。便利ですよね。でも、もし泥棒がこの合鍵を盗み出せたらどうなるでしょうか? あなたになりすまして、勝手に買い物をしたり、個人情報を書き換えたりできてしまいますよね。
この「合鍵を盗まれる(悪用される)」攻撃の代表格がCSRF(クロスサイト・リクエスト・フォージェリ)です。
—
2. SameSite属性は「鍵の持ち出し禁止ルール」
ブラウザは、「他の悪いサイトから、あなたの合鍵を勝手に使わせないようにしよう」と考えました。そこで登場したのがSameSite属性です。
- SameSite=Strict: 自分のサイト以外からは、絶対に合鍵を使わせない(一番頑丈)。
- SameSite=Lax: 基本はダメだけど、ユーザーがリンクをクリックして遷移した時だけは合鍵を使っていいよ(バランス型)。
- SameSite=None: どんなサイトからでも合鍵を使えるようにするよ(昔ながらの仕様)。
「えっ、じゃあ None なんて危ないから使わなきゃいいじゃん!」と思いますよね。その通りです。ただ、どうしても「埋め込みコンテンツ」や「外部との連携」で、どうしても他サイトから合鍵が必要なケースが一部だけ存在するのです。
—
3. なぜ「Secure属性」が必須になったのか?
ここで本題の「Secure属性」です。
SameSite=None を使うということは、「合鍵をどこからでも利用可能にする」という非常にリスクの高い状態を許可することになります。もし通信経路が暗号化されていない(HTTP通信)場合、ネットワークの途中で悪い奴がパケットを盗み聞き(盗聴)して、あなたの「合鍵」をコピーできてしまいます。
そこでブラウザはこう決めました。
「君がどうしても SameSite=None(どこでも鍵利用)を使いたいなら、その合鍵は絶対に盗聴不可能な『専用の金庫(HTTPS通信)』に入れて持ち運ぶことを条件にするよ」
これが、「SameSite=None を指定するなら、Secure属性をセットで付けなければならない」という仕様の正体です。
—
4. 具体的な実装コードを見てみよう
開発現場では、サーバー側でクッキーをセットする際にこの設定を行います。設定漏れがあると、最新のブラウザではクッキーが保存されず、ログイン状態が維持できないという事態になります。
Node.js (Express) の例
res.cookie(‘session_id’, ‘your_secret_token’, {
httpOnly: true, // JSから盗まれないようにする(必須!)
secure: true, // HTTPS通信でのみ送信する(今回の主役!)
sameSite: ‘none’ // 他サイト間でもクッキーを送る
});
PHP の例
// session_startの前に設定するのがコツです
session_set_cookie_params([
‘lifetime’ => 0,
‘path’ => ‘/’,
‘domain’ => ‘example.com’,
‘secure’ => true, // HTTPS強制
‘httponly’ => true, // JavaScriptからのアクセス禁止
‘samesite’ => ‘None’ // 他サイト間連携を許可
]);
session_start();
—
5. まとめ:一歩ずつ防犯レベルを上げよう
今回学んだ「SameSite=None + Secure」の設定は、いわば「合鍵を渡すなら、必ず防弾チョッキを着て届けてね」というルールです。
1. HTTPSは当たり前: 今の時代、HTTPは「玄関の鍵を開けっ放し」と同じです。まずは全ページHTTPS化を徹底しましょう。
2. 基本はLaxでOK: 必要に迫られない限り、SameSite=None を使う必要はありません。まずは Lax から始めてみましょう。
3. 属性のセットを確認: もし None を使う時は、必ず Secure が付いているか、コードレビューで指差し確認してください。
セキュリティは、一度に完璧にする必要はありません。こうして一つずつ「なぜ必要なのか」を理解して積み上げていくことが、結果として最強の防御につながります。
これからも一緒に、安全なWebの世界を作っていきましょう!応援しています。
コメント