6-11 CSRFとは?仕組みと対策

Web開発学習ロードマップ

前の記事では、
XSS(クロスサイトスクリプティング) について学びました。

XSSは
「表示時の安全性」がテーマでしたが、
今回扱う CSRF
「意図しない操作をさせられる危険性」 がテーマです。

フォーム処理を行うPHPでは、
CSRF対策は必須 です。

この記事では、
CSRFとは何か、どのように攻撃されるのか、
PHPでの基本的な対策方法

コード付きで解説します。


この記事で学べること

・CSRFとは何か
・CSRF攻撃の仕組み
・なぜCSRFが危険なのか
・PHPでの基本的なCSRF対策
・XSSとの違い


CSRFとは何か

CSRF(Cross Site Request Forgery)とは、
ユーザーが意図しないリクエストを、
正規ユーザーとして送信させられてしまう攻撃
です。

日本語では、
クロスサイト・リクエスト・フォージェリ
と呼ばれます。


CSRFのポイントは「なりすまし」

CSRFの最大の特徴は、

・攻撃者がログインするわけではない
・被害者がログインした状態を利用する

という点です。

つまり、

「ログイン中のユーザー自身が、
気づかないうちに操作してしまう」

これがCSRFです。


CSRF攻撃の典型的な流れ

CSRF攻撃は、
次のような流れで行われます。

  1. ユーザーがWebサービスにログイン

  2. ログイン状態のまま、別の悪意あるサイトを閲覧

  3. そのサイトから、勝手にリクエストが送信される

  4. サーバーは「正規ユーザーの操作」と判断

  5. 処理が実行されてしまう


CSRFが起きると何が問題か

CSRFが起きると、
次のような被害が発生します。

・パスワード変更
・メールアドレス変更
・退会処理
・投稿・削除操作

これらが
本人の意思とは無関係に実行
される可能性があります。


なぜCSRFが起きるのか

CSRFが起きる原因は、
次の一点に集約されます。

「そのリクエストが本当に本人の操作かどうかを確認していない」

サーバー側が、

・ログインしている
という理由だけで
・正当な操作だと判断

してしまうことが問題です。


XSSとCSRFの違い

混同しやすいので、
ここで整理します。

・XSS
 → 不正なスクリプトを実行させる
・CSRF
 → 不正なリクエストを実行させる

どちらも危険ですが、
攻撃の方向性が違う
点を理解しておきましょう。


CSRF対策の基本は「トークン」

CSRF対策の基本は、
CSRFトークン を使う方法です。

トークンとは、

・推測できない文字列
・フォームごとに発行
・送信時に一緒に送る

という仕組みです。


CSRFトークンの考え方

CSRFトークンを使うと、

・正規のフォームから送信されたか
・第三者サイトからの送信ではないか

を判定できます。

「正しいトークンがあるかどうか」
が、判断材料になります。


PHPでCSRFトークンを生成する

まずは、
トークンを生成して
セッションに保存します。

サンプルコード①:トークン生成

<?php
session_start();

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

コードの解説

・session_start
 → セッションを使う
・random_bytes
 → 安全なランダム文字列生成
・$_SESSION に保存

このトークンは、
ユーザーごとに保持 されます。


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

次に、
フォームにトークンを含めます。

サンプルコード②:フォーム側

<form method="post" action="result.php">
  <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
  <button type="submit">送信</button>
</form>

ポイント

・hidden フィールドで送信
・ユーザーには見えない
・正規フォームからしか送れない

これがCSRF対策の要です。


送信時にトークンを検証する

フォーム送信後、
PHP側でトークンを確認します。

サンプルコード③:トークン検証

<?php
session_start();

if (
  empty($_POST['csrf_token']) ||
  $_POST['csrf_token'] !== $_SESSION['csrf_token']
) {
  echo '不正なリクエストです';
  exit;
}

echo '正規のリクエストです';

コードの解説

・トークンが存在するか
・セッションの値と一致するか

どちらかでも失敗したら、
処理を中断 します。


CSRF対策は「更新系処理」に必須

CSRF対策は、
特に次の処理で必須です。

・登録
・更新
・削除
・設定変更

逆に、

・表示のみ
・検索

などでは、
必須ではないケースもあります。


初心者がよくやるミス

CSRF対策で多いミスです。

・ログインしているから安心と思う
・トークンを検証していない
・GETリクエストで更新処理を行う

「更新処理=CSRF対策必須」
と覚えてください。


フレームワークがCSRF対策をする理由

Laravelなどのフレームワークが
CSRF対策を自動で行うのは、

・人為的ミスが起きやすい
・忘れると致命的

だからです。

基礎を理解しておくことで、
フレームワークの仕組みも
正しく理解できます。


まとめ

CSRFは、

・ログイン中のユーザーを利用した
・意図しない操作を行わせる攻撃

です。

対策の基本は、

・CSRFトークンを発行
・フォームに埋め込む
・送信時に検証する

この流れを守ることです。

ここまで理解できれば、
PHPフォーム処理は「実務レベルの安全性」
に到達しています。


次に読むべき記事

▶ 次の記事
6-12 PHPでセッションを使って状態を管理する

▶ 関連記事
6-10 XSSとは?なぜ危険なのか

コメント