【セキュリティ】クロスサイト・リクエストフォージェリ(CSRF)
クロスサイト・リクエストフォージェリ(CSRF)
脆弱性が生まれる原因
背景としてWebの性質がある。
① form要素のaction属性にはどのドメインのURLでも指定できる
・罠などのサイトからでも、攻撃対象サイトにリクエストを送信できる
② クッキーに保管されたセッションIDは、対象サイトに自動的に送信される
・罠経由のリクエストに対しても、セッションIDのクッキー値が送信されるので、認証された状態で攻撃リクエストが送信される
(例)HTTPリクエストの内容がほぼ同じだが、Refererヘッダのみ異なる。
意図したHTTPリクエスト
※『体系的に学ぶ安全なWebアプリケーションの作り方 第2版(固定版) 脆弱性が生まれる原理と対策の実践』より引用
・Refererがパスワード入力画面のURLを指している。
CSRFによる意図しないHTTPリクエスト
※『体系的に学ぶ安全なWebアプリケーションの作り方 第2版(固定版) 脆弱性が生まれる原理と対策の実践』より引用
・Refererが罠ページのURLを指している。
通常のアプリケーションでは、Refererの値をチェックしないため、CSRF脆弱性が混入する。
対策
「重要な処理」に対するリクエストが正規利用者の意図したものであることを確認する必要がある。
① CSRF 対策の必要なページを区別する
CSRF対策はすべてのページに実施するものではない。
パスワードの変更や個人情報変更などの確定画面といった、他のサイトから勝手に実行されると困るページに対して対策する必要がある。
開発プロセスの中で行なうべきこと
・要件定義工程で機能一覧を作成し、、CSRF対策の必要な機能にマークする
・基本設計工程で画面遷移図を作成し、CSRF対策の必要なページにマークする
・開発工程でCSRF対策を作り込む
② 正規利用者の意図したリクエストを確認できるよう実装する
CSRF対策として必要なことは、正規利用者の意図したリクエストであることの確認
※『体系的に学ぶ安全なWebアプリケーションの作り方 第2版(固定版) 脆弱性が生まれる原理と対策の実践』より引用
※正規利用者の意図したリクエスト…対象のアプリケーション画面上で正規利用者が自ら「実行」ボタンを押した結果のリクエスト
※意図しないリクエスト… 罠のサイトからのリクエスト
意図したリクエストかどうかを判定する方法
① 秘密情報(トークン)の埋め込み
CSRF対策が必要な登録画面や注文確定画面などのページに対して、第三者が知り得ない秘密情報を要求するようにすれば、不正なリクエストを送信させられても、アプリケーション側で判別することができる。
アプリケーションフレームワーク側でトークンの生成とチェックの機能を持つものが増えてきており、こういった機能を有効活用することで対策が可能。
トークンは第三者に推測されにくい乱数を用いて生成する。
※PHPで利用できる暗号論的擬似乱数生成機
・/dev/urandomから読み込み
・openssl_random_pseudo_bytes
・random_bytes
トークンはセッション変数に記憶する。
第三者に予測不可能なトークンを要求することにより、CSRF攻撃を防ぐことが可能。
トークンが空でないことを確認すること。
入力 - 確認 - 実行形式の画面のように、3段階以上の遷移がある場合でも、トークンを埋め込むページは、実行ページの直前のページ。
トークンを受け付けるリクエスト(「重要な処理」を受け付けるリクエスト)はPOSTメソッドにする必要がある。
→ GETメソッドで機密情報を送ると、Refererにより機密情報が外部に漏れる可能性があるため。
② パスワード再入力
CSRF対策以外のパスワード再入力の目的
・物品購入などに先立って、正規利用者であることを確認する
・共有PCで別人が操作している状況などがなく、本当に正規の利用者であることを確認する
パスワードを確認するタイミングは、最終の実行ページ。
画面が3画面以上にまたがる入力 - 確認 - 実行形式の場合や、ウィザード形式の場合でもパスワードを確認するタイミングは最後の実行ページ。
対象ページ以外で確認を求めると煩雑で使いにくいアプリケーションになってしまう。
※ウィザード形式:ソフトウェアやWebサービスなどで、ユーザーが複雑な設定や操作を手順に従って簡単に行えるように設計されたユーザーインターフェースの一種のことで、視覚的なガイドがある。
③ Refererのチェック
「重要な処理」を実行するページでRefererを確認することで、CSRF対策になる。
正規のリクエストとCSRF攻撃によるリクエストでは、Refererフィールドの内容が異なっているため。
正規のリクエストでは、実行画面の1つ手前のページ(入力画面や確認画面など)に対するURLがRefererとしてセットされているはずなので、それを確認する。
Refererの確認によるCSRF対策は、「重要な処理」の実行ページだけの追加で済むため、他の対策のように2画面にまたがって処理を追加する必要はない。
※Refererのチェックは漏れが生じやすいので注意が必要。
Refererをチェックする場合は、前方一致検索で絶対URLをチェックすることと、ドメイン名の後のスラッシュ「/」まで含めてチェックすることが必須条件。
CSRF対策の比較
※『体系的に学ぶ安全なWebアプリケーションの作り方 第2版(固定版) 脆弱性が生まれる原理と対策の実践』より引用
CSRF攻撃への保険的対策
「重要な処理」の実行後に、対象利用者の登録済みメールアドレスに対して、処理内容の通知メールを送信すること
CSRF攻撃を受けた際に、利用者が早期に気づくことができるため、被害を最小限にとどめることができる可能性がある。
※メールは平文で送信されるものであるため、通知メールには重要情報は含ませず、「重要な処理」が実行されたことのみにとどめること。
まとめ
本記事では、『体系的に学ぶ安全なWebアプリケーションの作り方 第2版(固定版)脆弱性が生まれる原理と対策の実践』を元に学習したことをメモとしてまとめています。
とても参考になるため一読をオススメします。
参考・画像引用元UR
『体系的に学ぶ安全なWebアプリケーションの作り方 第2版(固定版) 脆弱性が生まれる原理と対策の実践』






Discussion