問題
以下はテスト用に「ログインしたことにする」スクリプト(mypage.php)。ログイン状態で呼び出すこともでき、いずれの場合でもログインユーザのメールアドレスを表示します。
以下はメールアドレス変更フォーム(chgmailform.php)。CSRF対策用のワンタイムトークンを生成してhiddenパラメータtokenにセットします。<?php // mypage.php : ログインしたことにする確認用のスクリプト session_start(); if (empty($_SESSION['id'])) { // ログインしたことにしてメールアドレスも初期化 $_SESSION['id'] = 'alice'; $_SESSION['mail'] = 'alice@example.com'; } ?><body> ログイン中(id:<?php echo htmlspecialchars($_SESSION['id'], ENT_QUOTES, 'UTF-8'); ?>)<br> メールアドレス:<?php echo htmlspecialchars($_SESSION['mail'], ENT_QUOTES, 'UTF-8'); ?><br> <a href="chgmailform.php">メールアドレス変更</a><br> </body>
以下はメールアドレス変更プログラム(chgmail.php)。ワンタイムトークン確認の後、メールアドレスを変更(実際にはセッション変数のみ変更)します。<?php // chgmailform.php メールアドレス変更フォーム session_start(); if (empty($_SESSION['id'])) { die('ログインしてください'); } $token = bin2hex(random_bytes(24)); // ワンタイムトークン生成 $_SESSION['token'] = $token; ?><body> <form action="chgmail.php" method="POST"> メールアドレス<input name="mail"><BR> <input type=submit value="メールアドレス変更"> <input type="hidden" name="token" value="<?php echo htmlspecialchars($token, ENT_COMPAT, 'UTF-8'); ?>"> </form> </body>
<?php // chgmail.php メールアドレス変更実行 session_start(); if (empty($_SESSION['id'])) { die('ログインしてください'); } $id = $_SESSION['id']; // ユーザIDの取り出し if ($_POST['token'] !== $_SESSION['token']) { // ワンタイムトークン確認 die('正規の画面からご使用ください'); } unset($_SESSION['token']); // 使用済みトークンの削除 $mail = $_POST['mail']; $_SESSION['mail'] = $mail; ?> <body> <?php echo htmlspecialchars($id, ENT_COMPAT, 'UTF-8'); ?>さんのメールアドレスを<?php echo htmlspecialchars($mail, ENT_COMPAT, 'UTF-8'); ?>に変更しました<br> <a href="mypage.php">マイページ</a> </body>
以下は実行例です。まず mypage.php にアクセスすると、ログインしたことにしてセッション変数を初期化し、現在のメールアドレスを表示します。「メールアドレス変更」のリンクをクリックします。
以下の画面でメールアドレスを適当に入力し、「メールアドレス変更」ボタンを押します。
以下のように、メールアドレスが変更されたことを確認します。その後マイページに遷移して、メールアドレスの確認をするとよいでしょう。
設問
利用者(被害者)がmypage.phpを閲覧した状態(ログイン中を想定)で、罠ページを閲覧させることにより、CSRF攻撃でメールアドレスを変更してください。この攻撃を実現する罠ページのPoC(概念実証コード)が解答になります。解答は週明けに公開予定で、その際にもう少し難易度の高い第2の問題を紹介します。
0 件のコメント:
コメントを投稿