CSRFについて初心者が初心者向けにまとめてみました。
CSRF関連のエラーが発生したので、CSRFについて調べていましたが具体的にどのような手法(ソース)なのか乗っている記事が少なかったので備忘録としてもまとめています。
CSRFとは
色々と記事があるので割愛。
クロスサイトリクエストフォージェリ(CSRF) - Trend Micro
CSRF被害の流れ
利用者が対象のサービスにログイン
→クライアントPCで不正なURLをクリック
→自分のアカウントで勝手にクレジット購入される、パスワードが変更されるなど。
3分でわかるXSSとCSRFの違い
CSRFのやり方
urlを踏んだ先にどのようなコードが書かれているか。パスワード不正変更を例にする。
<form action="https://hack-csrf-sample.herokuapp.com/mypage/edit" method="POST">
<input name="userId" value="hogehogehacker" />
<input name="password" value="hogehogehacker" />
</form>
<script>
var form = document.querySelector("form");
form.submit()
</script>
パスワードの変更を例にすると、
①urlをクリックした先のhtmlのformにリクエストするパラメーターを入れ(今回だったら変更するパスワードとユーザーID)
②このページが開いた瞬間にjavascriptでパスワード変更のリクエストを送っている。
WEBエンジニアなら必ず知っておくべき「CSRF」のサンプルサイトを作ってみた 参照
CSRFの対策
一例
$_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(16));
<form action="" method="POST">
<input type="text" value="" name="userId">
<input type="text" value="" name="password">
<input type="hidden" value="<?= h($_SESSION["token"]) ?>" name="token"> ←生成したトークン付与
<input type="submit" value="登録">
</form>
if (isset($_POST["token"]) && $_POST["token"] === $_SESSION["token"]) {
正規のフォームからのリクエスト
} else {
非正規のフォームからのリクエスト
}
クライアント側のリクエストのパラメーターにサーバー側で作成した、トークンを入れておくことで、サーバーがレスポンスしたformかどうか確認している。(不正なユーザーが作成したformではないか確認)