分12前回は,Webアプリケーションにおける受動的攻撃の代表例の1つであるXSSについて,原理や対策を振り返りました。今回は,同じく受動的攻撃の代表例であるCSRF,オープンリダイレクト,クリックジャッキングについて掘り下げて解説していきます。CSRF(クロスサイトリクエストフォージェリ)CSRFはどのように引き起こされるのかCSRFとは,たとえば掲示板の書き込みや設定情報の変更などの機能に対して,攻撃者のサイト上に設置されたフォームなどから強制的にリクエストを発行することで,ユーザーの意図していない操作と同様の結果をもたらす攻撃手法です。Webアプリケーションに永続的な副作用がある機能が攻撃の対象となります。http://example.jp/上に設置された掲示板で以下のようなHTMLがあったとします。value="書き込み"></form>このフォームを用いて,「⁠お名前」欄に「田中⁠」⁠,「⁠メッセージ」欄に「こんにちは。」を入力した状態で「書き込み」ボタンを押し,掲示板へテキストを書き込むときのブラウザからWebサーバへのHTTPリクエストは以下のようなものになります。application/x-www-form-urlencodedusername=田中&message=こんにちは。本来は,これら以外にも多くのHTTPリクエストヘッダが付与されますが,ここでは説明をかんたんにするために,必要最小限のヘッダのみを示しています。リクエストボディ中のusernameおよびmessageパラメータは,本来はURLエンコードされ`username=%E7%94%B0%E4%B8%AD&message=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E3%80%82`のようになりますが,これも説明をかんたんにするために,そのまま日本語のテキストで書き示しています。サーバ側は,このようなリクエストを受け取ると,usernameおよびmessageのパラメータをそれぞれ掲示板の内容として内部のデータベースに書き込みます。このような掲示板に対して,攻撃者が自身の罠サイトであるhttp://attacker.example.com/trap.html上に,以下のようなHTMLを用意したとします。name="message">これは犯罪の予告です。XX月XX日,YYYにて大規模な犯罪を行います。</form></body>フォーム自体は攻撃者のサイトであるhttp://attacker.example.com上にありますが,フォームの送信先が掲示板の設置されているhttp://example.jp/boardになっています。攻撃者は,このような罠ページを用意したのち,SNSやメール,ほかの掲示板などを経由してhttp://attacker.example.com/trap.htmlというURLを第三者に伝え,だれかがこのURLを訪問するのを待ちかまえます。ユーザーがうっかりこのURLをクリックして攻撃者の用意した罠サイトを訪問すると,ページを開いた瞬間にJavaScriptが動作し,以下のようなHTTPリクエストがユーザーのブラウザから掲示板の設置されているhttp://example.jpに対して発行され,攻撃者の用意した内容のメッセージ,すなわち犯罪予告がexample.jp上の掲示板に書き込まれてしまいます。application/x-www-form-urlencodedusername=名無しさん&message=これは犯罪の予告です。XX月XX日,YYYにて大規模な犯罪を行います。掲示板への書き込みのリクエストは,攻撃者ではなく,罠ページを閲覧したユーザーのブラウザから行われますので,掲示板上で書き込みのIPアドレスを記録している場合にはユーザーのIPアドレスが記録されます。そのため,掲示板への犯罪予告の書き込みに対して警察などによる捜査が行われた場合には,攻撃者ではなく,罠ページを閲覧したユーザーが捜査対象となってしまうこともありえます。このように,Webアプリケーションにおいて副作用の発生するリクエストを,罠ページなどを経由してユーザー自身に発生させる攻撃手法がCSRFです。ログインを利用してメールアドレスを強制的に変更してしまう仕組みでは次に,CSRFの対象となるWebアプリケーションが掲示板ではなくログイン機構を持つものであった場合を考えてみましょう。ログイン後の個人設定の変更においてメールアドレスを変更するためのフォームがあったとします。value="メールアドレスを変更する"></form>このフォームを用いて,メールアドレスとしてnewaddr@example.jpを設定した場合のブラウザからWebサーバへのHTTPリクエストは以下のようなものになります。application/x-www-form-urlencodedemail=newaddr@example.jpすでにWebアプリケーションにはログイン済みであるため,ログイン後のセッションIDであるCookieがリクエスト内のCookieリクエストヘッダとして送信されています。サーバ側は,このようなリクエストを受け取ると,データベース内に登録されているユーザーのメールアドレスをnewaddr@example.jpに変更して書き込みます。このような設定画面を持つWebアプリケーションに対して,攻撃者は自身の罠サイトであるhttp://attacker.example.com/trap.html上に今度は以下のようなHTMLを用意します。</form></body>攻撃者はこのような罠ページを用意したのち,先ほどの掲示板のときと同様に,http://attacker.example.com/trap.htmlというURLをSNSやメール,ほかの掲示板などを経由してほかのユーザーに伝え,そのユーザーが罠URLを訪れるのを待ちかまえます。ログイン済みのユーザーがこのURLを訪問すると,以下のようなHTTPリクエストがユーザー自身のブラウザからWebアプリケーションの設定画面に対して発行されます。application/x-www-form-urlencodedemail=hijack@attacker.example.comユーザー自身はWebアプリケーションにすでにログイン済みですので,Webアプリケーションに対してのリクエストにはセッションIDを含むCookieがそのまま付与されます。結果として,ユーザー自身は意図していないにも関わらず,メールアドレスが攻撃者のものに強制的に変更されてしまうことになります。このように,攻撃者の用意した罠ページを起点とし,ユーザー自身に攻撃対象となるサイトへのリクエストを発行させることによって,ユーザー自身が意図していない処理を行わせるのがCSRFです。CSRFへの対策CSRFへの対策としては,攻撃者が知りえない値をリクエスト内に埋め込む,すなわちフォーム内にhiddenを用いてトークンを埋め込むサーバ側でリクエストを受け取ったときに,そのトークンを確認するという方法がもっとも広く使われています。以下の例では,tokenという名前でhiddenが指定されたinputタグに,攻撃者には推測できないランダム値を埋め込んでいます。value="メールアドレスを変更する"></form><form>サーバ側では,formのPOSTリクエストを受け取ったときに,tokenの値が正しいものか検証することで,リクエストが正規の画面遷移によって発行されたものであることを確認できます。トークンを利用する方法以外にも,パスワードを再入力させる方法や,CAPTCHAなどを利用する方法もありますが,本稿では説明は省略します。クリックジャッキング著者プロフィールはせがわようすけ株式会社セキュアスカイ・テクノロジー常勤技術顧問。FirefoxをはじめWebアプリケーションに関する多数の脆弱性を発見。