カテゴリ: PHP 更新日: 2026/01/22

PHPのCSRF対策を完全理解!トークンを使った安全なフォーム送信の仕組みを初心者向けに徹底解説

PHP の CSRF 対策(トークンの活用)
PHP の CSRF 対策(トークンの活用)

先生と生徒の会話形式で理解しよう

生徒

「PHPでフォームを送信するときに“CSRF”という攻撃が危ないと聞いたんですが、どういうものなんですか?」

先生

「CSRFは、ユーザーが気づかないうちに勝手にフォームを送信させられてしまう攻撃のことだよ。とても危険だから、PHPでWebアプリを作るなら必ず対策が必要なんだ。」

生徒

「どうやって対策するんですか?」

先生

「“CSRFトークン”という秘密の合言葉を使うのが一般的だよ。今日は、その仕組みとPHPでの実装方法をくわしく説明していくね。」

-

1. CSRF攻撃とは?初心者にもわかる仕組み

1. CSRF攻撃とは?初心者にもわかる仕組み
1. CSRF攻撃とは?初心者にもわかる仕組み

CSRF(Cross-Site Request Forgery・クロスサイトリクエストフォージェリ)とは、ユーザーが意図していないのに勝手に操作を実行されてしまう攻撃のことです。

例えば、あなたがショッピングサイトにログイン中だとします。その状態で悪意あるサイトを開くと、あなたが知らないうちに「注文確定のリクエスト」が送られてしまうことがあります。これは “リクエストを偽造される” という意味で、PHPのWebアプリでは特に注意が必要です。

Webアプリの操作は「ログインしている本人の意図」が前提ですが、CSRF攻撃はその前提を破壊します。そのため、フォーム送信やボタン操作には必ず安全な仕組みが必要です。

2. CSRFを防ぐには「秘密のトークン」が必須

2. CSRFを防ぐには「秘密のトークン」が必須
2. CSRFを防ぐには「秘密のトークン」が必須

CSRF対策で最も一般的なのが「CSRFトークン(令和風に言えば “秘密の合言葉”)」です。このトークンをフォームに埋め込み、送信されたときに一致するかどうかをサーバー側でチェックします。

ポイントは次の3つです:

  • トークンはユーザーごとに異なるランダム文字列
  • トークンをセッションに保存しておく
  • フォームにもトークンを入れて送信し、一致を確認

これにより、外部サイトから勝手にリクエストを送られてもトークンが一致しないため不正なリクエストは拒否されます。

3. PHPでCSRFトークンを作る方法(超基本)

3. PHPでCSRFトークンを作る方法(超基本)
3. PHPでCSRFトークンを作る方法(超基本)

まず、トークンを生成し、セッションに保存します。ランダムな文字列を生成するには bin2hex(random_bytes()) を使うのが安全です。


session_start();

if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

random_bytes は暗号学的に安全な乱数を生成します。セキュリティ用途で必ず使うべき関数です。

4. フォームにCSRFトークンを埋め込む

4. フォームにCSRFトークンを埋め込む
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チェックを行う

5. PHPでCSRFチェックを行う
5. PHPでCSRFチェックを行う

送信されたトークンがセッションのトークンと一致しているかを確認します。もし違っていた場合は不正なリクエストとして処理を中止します。


session_start();

if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die('不正なアクセスです。');
}

echo "コメントを受け付けました!";

このチェックがPHPのCSRF対策の中心的な部分です。これを入れておくだけで、外部サイトからの偽造リクエストをほぼ100%防ぐことができます。

6. トークンは使い捨てにするのが安全

6. トークンは使い捨てにするのが安全
6. トークンは使い捨てにするのが安全

さらに強固にするなら、「一度使ったトークンは破棄する」という方法があります。これはワンタイムトークンという方式で、フォーム送信が完了したらトークンを削除し、新しいトークンを作ります。

こうすることで、もしトークンが盗まれたとしても再利用される可能性を減らせます。

7. なぜCSRF対策は必須なのか?初心者でも理解できる具体例

7. なぜCSRF対策は必須なのか?初心者でも理解できる具体例
7. なぜCSRF対策は必須なのか?初心者でも理解できる具体例

例えば、銀行のWebアプリで「送金する」ボタンがあったとします。

CSRF対策がないと、悪意あるサイトを開いただけで、あなたのログイン状態を利用して勝手に送金される可能性があります。

これは PHP に限らず、すべてのWebアプリで起こりうる危険です。だからこそ、トークンによるCSRF対策は “必須のセキュリティ設定” として世界中の開発者が実装しています。

8. CSRF対策でよくある間違いと注意点

8. CSRF対策でよくある間違いと注意点
8. CSRF対策でよくある間違いと注意点

初心者がやってしまいがちな注意点もまとめます。

  • トークンを固定してしまう(毎回新しいものを作るべき)
  • GETリクエストにトークンをつける(URLは漏れやすいので危険)
  • トークンのチェックを忘れる(フォーム作って満足してしまう)
  • random_bytes の代わりに mt_rand を使う(セキュアではない)

とくに「トークンをチェックしていない」は多いミスなので注意してください。

コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

カテゴリの一覧へ
新着記事
New1
PHP
PHPのCookieセキュリティを完全ガイド!初心者でもわかるSecureとHttpOnlyの使い方
New2
PHP
PHPのCSRF対策を完全理解!トークンを使った安全なフォーム送信の仕組みを初心者向けに徹底解説
New3
PHP
PHPのSQLインジェクション対策を完全解説!初心者でも安全にデータベースを扱う方法
New4
PHP
PHPでカウントダウンタイマーを作る方法!初心者向けにやさしく解説
-
人気記事
No.1
Java&Spring記事人気No1
Python
Pythonでテキストファイルを1行ずつ読み込む方法(readline() / readlines())
No.2
Java&Spring記事人気No2
PHP
初心者向けPHPでMySQLからデータを取得する方法(SELECT文)完全ガイド
No.3
Java&Spring記事人気No3
Python
Pythonのリストの重複を削除する方法を解説!初心者向けにsetとdict.fromkeysの使い方をやさしく説明
No.4
Java&Spring記事人気No4
Python
Pythonで経過時間を測る方法をやさしく解説!初心者向けtime.perf_counterとtime.sleepの使い方
No.5
Java&Spring記事人気No5
Python
Pythonでエラースタックトレースを表示・取得する方法を徹底解説!初心者向け例外処理入門
No.6
Java&Spring記事人気No6
PHP
PHPのOAuth認証をやさしく解説!Google・Facebookログインを初心者向けに実装しよう
No.7
Java&Spring記事人気No7
Python
PythonでExcelファイル(.xlsx)を操作する方法を徹底解説!初心者でもできるopenpyxl・pandasの使い方
No.8
Java&Spring記事人気No8
Python
PythonでMySQLに接続する方法を完全解説!初心者でもわかるpymysqlの基本
-
-