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

Web開発学習ロードマップ

前の記事では、
XSS(クロスサイトスクリプティング) という
「表示時の危険性」について学びました。

今回扱う CSRF は、
それとは別の方向から攻撃が行われます。

CSRFは、
ユーザーが意図していない操作を、
正規ユーザーとして実行させられてしまう脆弱性
です。

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

この記事では、
CSRFとは何か、なぜ危険なのか、
PHPでの基本的な対策方法

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


この記事で学べること

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


CSRFとは何か

CSRF(Cross Site Request Forgery)とは、
ログイン中のユーザーの権限を悪用し、
意図しないリクエストを送信させる攻撃
です。

攻撃者自身がログインするわけではなく、
被害者がログインしている状態 を利用する点が特徴です。


CSRF攻撃の典型的な流れ

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

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

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

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

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

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

ユーザーは、
自分が操作したつもりがなくても処理が実行される
という点が問題です。


CSRFで何が起こるのか

CSRFが成立すると、
次のような被害が起こります。

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

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


なぜCSRFが起きるのか

原因はシンプルです。

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

サーバー側が、

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

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


XSSとCSRFの違い

ここで整理しておきましょう。

・XSS
 → スクリプトを実行させる攻撃

・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 フィールドで送信
・ユーザーには見えない
・正規フォームからしか送信できない


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

フォーム送信後、
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トークンを発行
・フォームに埋め込む
・送信時に検証する

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

ここまで理解できれば、
フォーム処理に必要な
セキュリティ基礎は完成 です。


次に読むべき記事

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

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

コメント