My Photo

« クロスサイトリクエストフォージェリ(CSRF)その2 | Main | セッション管理の不備 その1 »

November 04, 2013

クロスサイトリクエストフォージェリ(CSRF)その3

関連記事:
クロスサイトリクエストフォージェリ(CSRF)その1
クロスサイトリクエストフォージェリ(CSRF)その2

対策

CSRF攻撃を防ぐためには、「重要な処理」に対するリクエストが正規利用者の意図したものであることを確認する必要がある。そのために以下の2点を実施する。

  • CSRF対策の必要なページを区別する。
  • 正規利用者の意図したリクエストを区別できるように実装する。

CSRF対策の必要なページを区別する

CSRF対策はすべてのページに実施するのもではない。むしろ対策の必要のないページの方がはるかに多い。
ECサイトの物品購入、パスワード変更、個人情報編集などの確定画面は他のサイトから勝手実行されると問題があるページであるので、このようなページにはCSRF対策を施す。
開発プロセスでは以下のようにする。

  • 要件定義で機能一覧を作成し、CSRF対策が必要な機能をマークする。
  • 基本設計で画面遷移図を作成し、CSRF対策が必要なページをマークする。
  • 実装でCSRF対策を作りこむ。

正規利用者を意図したリクエストであることを確認する

具体的な方法として以下の3種類が用いられる。

  • 秘密情報(トークン)の埋め込み
  • パスワード再入力
  • Refererチェック

秘密情報(トークン)の埋め込み

CSRF攻撃への対策が必要なページに対して第三者が知りえない秘密情報を要求するようにすれば、CSRF攻撃のリクエストをアプリケーション側で判別できる。このような目的で使用される秘密情報の事をトークン(token)と呼ぶ。セッションIDをトークンとして利用することができる。
下記にトークン利用の実装例を示す。

実行画面の直前の画面
<from action="change_password.php" method="post">
新パスワード<input type="password" name="pwd"><br>
<input type="hidden" name="token" value=<?php
echo htmlspecialchars(session_id(), ENT_COMPAT, 'UTF-8'); ?>">
<input type="submit" value="パスワード変更">
</form>
トークンの確認
session_start();
if (session_id() !== $_POST['token']) {
	die('<エラーメッセージ>');
}
// 以下、重要な処理

入力-確認-実行形式のように3段階以上の遷移がある場合でも、トークンを埋め込むページは実行の直前のページだけである。
また、トークンを受け付けるリクエスト(重要な処理を受け付けるリクエスト)はPOSTメソッドにする必要がある。GETメソッドで送信するとRefererにより機密情報が外部に漏れる可能性があるからである。

トークンには使い捨てのワンタイム・トークンがある。ワンタイム・トークンは必要になる度に生成する。
ワンタイム・トークンを利用する典型的なケースはリプレイ攻撃(Replay attack)対策が必要な場合である。リプレイ攻撃は暗号化されたリクエストを盗聴してその内容を丸ごと再送すること成りすましなどの攻撃をする手法である。
ワンタイム・パスワードの利用には以下のような主張がある。

  • CSRF攻撃は盗聴やリプレイ攻撃とは無関係であり、ワンタイム・トークンを用いる必然性はない。
  • ワンタイム・トークンがセッションIDをトークンとする方法に比べて安全になる根拠はない。
  • ワンタイム・トークンを用いることで正当な操作までエラーになる場合がある。

パスワードの再入力

パスワード再入力はCSRF対策以外に、次の目的で利用される。

  • 物品の購入などに先立って、利用者の意思を念押しして確認する。
  • 共有PCで別人が操作している状況などがなく、本当に正規の利用者であることを確認する。

ページが上記の要件を満たしている場合はパスワード再入力によってCSRF対策を行うとよい。逆にそれ以外のページ(ログアウト処理など)でパスワードの再入力を求めると、煩雑で使いにくくなる。

Refererのチェック

正規リクエストでは実行画面の1つ手前のページ(入力画面や確認画面など)に対するURLがRefererとしてセットされているはずなので、それをチェックする。

この方式の欠点は、Refererが送信されない場合はそのページを実行できないことである。セキュリティソフトやブラウザによってRefererを抑止している利用者もいる。携帯電話のブラウザではRefererが送信されないものや送信を制御できるものもある。

また、Refererのチェックには漏れが生じやすいので注意が必要である。下記は脆弱性があるチェックの実装の例である。"example.jp"の後のスラッシュをチェックしていないため、例えば"http://example.jp.trap.example.com/trap.html"がチェックを通過してしまう。

if (preg_match('#^http://example\.jp#', @$_SERVER['HTTP_REFERER']) !== 1) {
	// エラー処理
}

CSRF攻撃への保険的対策

重要な処理の実行後に、対象利用者の登録済みメールアドレスに対して処理内容の通知メールを送信することを推奨する。
万一CSRF攻撃を受けた場合に利用者が早期に気付くことができ、被害を最小限にとどめることができる可能性がある。
通知メールによってCSRF攻撃以外の攻撃で成りすましによって重要な処理が悪用されたことを早期に気付くことができるので、メリットが大きい。
ただし、通知メールには重要情報は含ませず、重要な処理が実行されたことのみを通知するにとどめるべきである。詳細内容はWEBアプリケーションにログインして閲覧してもらうようにする。

参考文献:体系的に学ぶWebアプリケーションの作り方 4.5.1 クロスサイト・リクエストフォージェリ(CSRF)

体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践
徳丸 浩

ソフトバンククリエイティブ 2011-03-03
売り上げランキング : 4070

Amazonで詳しく見る
by G-Tools

« クロスサイトリクエストフォージェリ(CSRF)その2 | Main | セッション管理の不備 その1 »

PHP」カテゴリの記事

セキュリティ」カテゴリの記事

Comments

Post a comment

(Not displayed with comment.)

TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/26461/58511842

Listed below are links to weblogs that reference クロスサイトリクエストフォージェリ(CSRF)その3:

« クロスサイトリクエストフォージェリ(CSRF)その2 | Main | セッション管理の不備 その1 »

March 2017
Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof