本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。
はじめに
CSRFとは
これがCSRFの被害が発生する大まかな流れです。
(※)コミット機能
データの登録、変更、削除を伴う機能
対策
○罠サイトにアクセスした場合のリクエスト流れ図(対策済み)
またこのほかにもHTTPヘッダを利用した対策や、前述のCookieの属性値を設定するといった緩和策もあります。
検出例
それでは、実際に弊社の診断で検出されたCSRFの事例について見ていきましょう。
・機能を示すパラメータを操作してトークン検証を回避するケース
Web サイトの構築方法や使用しているフレームワークによっては、Webサイトの機能を表すパラメータを送信しているサイトを見かけます。
例として商品の購入を行うような機能にて、商品選択後に確認画面が表示され、そこで確認を押した際に実際の購入が行われるようなWebサイトを想定します。
〇商品選択画面イメージ
〇確認画面イメージ
〇完了画面イメージ
〇確認画面へのHTTPリクエスト
POST /purchase HTTP/1.1 Cookie: SESSION=4d2h58vpiqivu7tdumr8h2gepm ...(省略)... item_id=A&op=confirm
〇完了画面へのHTTPリクエスト(実際にコミットが行われるHTTPリクエスト)
POST /purchase HTTP/1.1 Cookie: SESSION=4d2h58vpiqivu7tdumr8h2gepm ...(省略)... token=L5iIEWYRifnXaMF2caQW6Ph4rx3cUHBWq6Irj1p5&op=complete
POST /purchase HTTP/1.1 Cookie: SESSION=4d2h58vpiqivu7tdumr8h2gepm ...(省略)... item_id=A&op=complete
・トークン不備のエラーが発生するもコミットが実行されるケース
〇完了画面へのHTTPリクエスト
POST /purchase HTTP/1.1 Cookie: SESSION=gk4jp3tbdasrti5fkhblhpcilv ...(省略)... token=AeEHsWFCT1K8HTsyselMaoAT1ElHTz7Y4hpmnmpG&op=complete
〇トークンのパラメータを削除して送信するHTTPリクエスト
POST /purchase HTTP/1.1 Cookie: SESSION=gk4jp3tbdasrti5fkhblhpcilv ...(省略)... op=complete
上記の例はトークンの検証ロジック自体はあるけど、パラメータを完全に削除した場合に想定していない処理フローを通ってしまっている可能性や、トークンの検証前にデータのコミット処理が実行されてしまっていることなどが考えられます。
フレームワークを使用している場合はこのようなケースは発生しづらいと思われますが、CSRF対策トークンの生成、検証ロジックを独自実装している場合などは要注意です。
・リクエストボディ部がJSON形式のケース
CSRFはJSON形式のリクエストでも検出されることがあります。
例としてCSRF対策を実施していない、以下のような商品をお気に入り登録するリクエストを考えます。
〇CSRF対策を実施していないJSONを用いたHTTPリクエスト
POST /api/favorites/add Cookie: SESSION=0kj8pem1824iq21m6ge1edp96j Content-Type: application/json … { “item_id”:12 }
ここからは診断員目線(攻撃者目線)で、このリクエストで攻撃を行うことを考えます。
通常通り、上記リクエストの送信を行う罠サイトを作成すると一つ問題が発生します。
それはContent-Typeがapplication/jsonであるため、罠サイトからのリクエスト送信時にCORSプリフライトが発生してしまいます。CORSプリフライトが発生してしまうと、攻撃リクエストの送信にはサーバ側が適切なヘッダを返す必要があり、攻撃への障壁が一つ増えてしまいます。(この場合、サーバは適切なAccess-Control-Allow-Headersを返す必要があります)
ここで使えるテクニックとして、リクエストのContent-Typeをtext/plainとし、リクエストボディ部でJSONパラメータを送信するように罠サイトを作成します。
この罠サイトから送信されるリクエストは前述の通りContent-Typeがtext/plainで送信されます。サーバ側でContent-Typeを適切に検証している場合は、この攻撃リクエストは失敗しますが、この方法によって正常なリクエストと同様にボディ部JSONとして解釈されてしまい、コミット処理が完了してしまうケースがあります。この原因の一例としては、フレームワークの機能を利用せずに、HTTPリクエストのボディ部を直接JSONとしてパースするような処理を実施していることなどが考えられます。
ちなみに余談ですが、上記の罠サイト例ではJavaScriptのXMLHttpRequestを使用することによってボディ部にJSONパラメータを設定しましたが、通常のhtmlタグを使用してJSONパラメータを送信するテクニックも実はあります。こういう細かなところでも診断員の技量が図られるなあと日々痛感しております。
おわりに
本稿では実際に診断で検出されたCSRFの様々なパターンを紹介しました。
冒頭でも触れましたが、最近はブラウザ側での対策も進んでおり、もしかしたら数年後にはCSRFという脆弱性自体メジャーでなくなる日が来るかもしれません。しかし、Webサイトの機能によっては大きな被害に発展することも考えられるため、まだまだ対策必須な脆弱性であることは変わりありません。
本稿が皆様のCSRFへの理解の助けになれば幸いです。それでは~~
おすすめ記事