PHPのCSRF対策を完全理解!トークンを使った安全なフォーム送信の仕組みを初心者向けに徹底解説
生徒
「PHPでフォームを送信するときに“CSRF”という攻撃が危ないと聞いたんですが、どういうものなんですか?」
先生
「CSRFは、ユーザーが気づかないうちに勝手にフォームを送信させられてしまう攻撃のことだよ。とても危険だから、PHPでWebアプリを作るなら必ず対策が必要なんだ。」
生徒
「どうやって対策するんですか?」
先生
「“CSRFトークン”という秘密の合言葉を使うのが一般的だよ。今日は、その仕組みとPHPでの実装方法をくわしく説明していくね。」
1. CSRF攻撃とは?初心者にもわかる仕組み
CSRF(Cross-Site Request Forgery・クロスサイトリクエストフォージェリ)とは、ユーザーが意図していないのに勝手に操作を実行されてしまう攻撃のことです。
例えば、あなたがショッピングサイトにログイン中だとします。その状態で悪意あるサイトを開くと、あなたが知らないうちに「注文確定のリクエスト」が送られてしまうことがあります。これは “リクエストを偽造される” という意味で、PHPのWebアプリでは特に注意が必要です。
Webアプリの操作は「ログインしている本人の意図」が前提ですが、CSRF攻撃はその前提を破壊します。そのため、フォーム送信やボタン操作には必ず安全な仕組みが必要です。
2. CSRFを防ぐには「秘密のトークン」が必須
CSRF対策で最も一般的なのが「CSRFトークン(令和風に言えば “秘密の合言葉”)」です。このトークンをフォームに埋め込み、送信されたときに一致するかどうかをサーバー側でチェックします。
ポイントは次の3つです:
- トークンはユーザーごとに異なるランダム文字列
- トークンをセッションに保存しておく
- フォームにもトークンを入れて送信し、一致を確認
これにより、外部サイトから勝手にリクエストを送られてもトークンが一致しないため不正なリクエストは拒否されます。
3. PHPでCSRFトークンを作る方法(超基本)
まず、トークンを生成し、セッションに保存します。ランダムな文字列を生成するには bin2hex(random_bytes()) を使うのが安全です。
session_start();
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
random_bytes は暗号学的に安全な乱数を生成します。セキュリティ用途で必ず使うべき関数です。
4. フォームにCSRFトークンを埋め込む
次に、生成したトークンをフォームに hidden(画面に表示しない入力欄)として埋め込みます。
<form action="submit.php" method="POST">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="text" name="comment">
<button type="submit">送信</button>
</form>
hiddenタグは、ユーザーには見えませんがフォーム送信時にサーバーへ送られる便利な仕組みです。
5. PHPでCSRFチェックを行う
送信されたトークンがセッションのトークンと一致しているかを確認します。もし違っていた場合は不正なリクエストとして処理を中止します。
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('不正なアクセスです。');
}
echo "コメントを受け付けました!";
このチェックがPHPのCSRF対策の中心的な部分です。これを入れておくだけで、外部サイトからの偽造リクエストをほぼ100%防ぐことができます。
6. トークンは使い捨てにするのが安全
さらに強固にするなら、「一度使ったトークンは破棄する」という方法があります。これはワンタイムトークンという方式で、フォーム送信が完了したらトークンを削除し、新しいトークンを作ります。
こうすることで、もしトークンが盗まれたとしても再利用される可能性を減らせます。
7. なぜCSRF対策は必須なのか?初心者でも理解できる具体例
例えば、銀行のWebアプリで「送金する」ボタンがあったとします。
CSRF対策がないと、悪意あるサイトを開いただけで、あなたのログイン状態を利用して勝手に送金される可能性があります。
これは PHP に限らず、すべてのWebアプリで起こりうる危険です。だからこそ、トークンによるCSRF対策は “必須のセキュリティ設定” として世界中の開発者が実装しています。
8. CSRF対策でよくある間違いと注意点
初心者がやってしまいがちな注意点もまとめます。
- トークンを固定してしまう(毎回新しいものを作るべき)
- GETリクエストにトークンをつける(URLは漏れやすいので危険)
- トークンのチェックを忘れる(フォーム作って満足してしまう)
- random_bytes の代わりに mt_rand を使う(セキュアではない)
とくに「トークンをチェックしていない」は多いミスなので注意してください。