「知らない間に、あなたの指が勝手に動く?」CSRF(クロスサイト・リクエスト・フォージェリ)の正体と防ぎ方
こんにちは!セキュリティの最前線で日々「泥棒」たちと追いかけっこをしているエンジニアです。
今日は、Webの世界で非常に厄介な「CSRF(クロスサイト・リクエスト・フォージェリ)」についてお話しします。名前を聞くと難しそうですが、仕組みを理解すれば怖くありません。まるで「家の鍵」をどう管理するかという、身近な防犯の話と同じなんです。
一歩ずつ、一緒に紐解いていきましょう!
—
1. CSRFって何?「泥棒」の巧妙な手口
CSRFをひとことで言うと、「ログイン中のあなたのブラウザを、悪意あるサイトが勝手に操る」攻撃です。
身近な例えで考えてみましょう
あなたが自分の家の玄関(Webサービス)に鍵をかけ、リビング(マイページ)でくつろいでいるとします。そこに、あなたの偽の友人(攻撃サイト)がやってきて、「ほら、この書類にサインして!」とあなたの手を掴んで、無理やりペンを握らせて勝手にサイン(リクエスト)を書いてしまう…これがCSRFです。
Webブラウザは、「ログイン済み」という状態(クッキーなど)を保持しています。攻撃者は、あなたがログインしていることを悪用し、あなたのブラウザに「パスワード変更」や「送金」といったリクエストをこっそり送信させるのです。
2. 攻撃はどうやって行われるの?
攻撃者は、あなたのブラウザが「自分自身で送信した」と思い込むような罠を仕掛けます。
1. 罠への誘導: あなたが攻撃者の用意した悪意あるサイトにアクセスします。
2. 自動送信: そのページには、バックグラウンドで自動的にリクエストを送る「隠しフォーム」や、特定のURLを読み込む仕掛けが埋め込まれています。
3. リクエストの実行: ブラウザは「あ、これ自分が見ているサイトからの命令だ!」と思い込み、あなたがログイン中のサービスへクッキー付きのリクエストを送信してしまいます。
4. 意図しない操作の完了: サービス側は「ログインしている本人からの操作だ」と勘違いし、パスワード変更や決済を実行してしまいます。
—
3. なぜこれで被害が出るの?
昔のWebサービスは、「リクエストが正しい場所から送られたか」を確認する仕組みが甘かったんです。鍵さえ持っていれば(ログイン中なら)、誰の指図でも受け入れてしまっていたんですね。
今の開発現場では、この「本人確認」に加えて、「本当に本人が意図してクリックしたのか?」を確認する仕組みを入れるのが常識です。
—
4. 今日からできる「防御の鍵」:アンチCSRFトークン
一番確実な対策は、「秘密の合い言葉(トークン)」をリクエストに混ぜることです。
仕組みの解説
Webサービス側は、フォームを表示するたびに「今回限りの使い捨てパスワード(CSRFトークン)」を生成し、サーバーに保存します。ユーザーが送信ボタンを押すとき、そのトークンも一緒に送ってもらいます。
もし攻撃者が勝手にリクエストを送ろうとしても、その「秘密の合い言葉」を知らないので、サーバー側で「お前は偽物だな!」と突き返せるようになるわけです。
実装イメージ(PHPの例)
// 1. セッションを開始して、トークンを生成・保存する
session_start();
if (empty($_SESSION[‘csrf_token’])) {
$_SESSION[‘csrf_token’] = bin2hex(random_bytes(32)); // 予測不能な文字列
}
// 2. フォームにトークンを埋め込む(隠しフィールド)
echo ‘‘;
// 3. 送信された時にチェックする
if ($_POST[‘csrf_token’] !== $_SESSION[‘csrf_token’]) {
die(“不正なリクエストです!”); // ここで泥棒を追い返す
}
—
5. さらに強固にするための「ヘッダー」という防壁
トークン以外にも、最近のブラウザには強力な盾が備わっています。それが「SameSite属性」です。
これはクッキーに設定する属性で、ブラウザに対して「このサイト以外からのリクエストには、このクッキー(ログイン情報)を絶対に使わせないで!」と指示するものです。
/ レスポンスヘッダーの設定例 /
Set-Cookie: session_id=abc123xyz; SameSite=Strict; Secure;
- SameSite=Strict: どんな状況でも、他サイトからのリンク経由ではクッキーを送信しない(一番安全!)。
- SameSite=Lax: 他サイトからのリンク遷移ならクッキーを送るが、POST送信などは拒否する(バランスが良い)。
—
最後に:完璧な防御なんてないからこそ
セキュリティの世界では、「これをやれば100%安心」という銀の弾丸はありません。しかし、「CSRFトークン」と「SameSite属性」、この2つを実装するだけで、あなたのサービスを守る強固な門番を置くことになります。
開発者の皆さん、まずは自分のアプリケーションのログインフォームや決済画面に、こうした「合い言葉」の仕組みが入っているか確認してみてください。
泥棒は常に「一番侵入しやすい家」を狙います。この記事を読んだあなたが、今日からしっかりと鍵を管理してくれることを願っています。
何か分からないことがあれば、いつでもコメント欄で聞いてくださいね。一緒に安全なWebの世界を作っていきましょう!
コメント