更新情報

みなさんこんにちは。野田貴子です。

ウェブサービスを作成する際には、CSRFやXSSを始めとした攻撃へのセキュリティを考えなくてはなりません。しかし最近はRuby on Railsのように最初からセキュリティ対策を備えているフレームワークも多く、特に意識せず開発を行っている人も多いかもしれませんね。

Ruby on RailsのCSRF対策について書かれたブログが注目を集めていたので、一部を紹介しておきたいと思います。

・CSRFとは

クロスサイトリクエストフォージェリー(CSRF)とは、攻撃者が被害者にリンクをクリックさせる、あるいはページを訪問させ、対象のサイトにリクエストを送らせる不正な行為のことです。この攻撃は被害者が対象のアプリケーションで認証済みになっている時(例えばブラウザの別タブでそのアプリケーションにログイン済みの場合)に成功します。

通常、利用者がアプリケーションにログインし認証されると、アプリケーションは利用者のブラウザにセッションクッキーを1つ保存します。このセッションクッキーは利用者によるすべてのHTTPリクエストと一緒に送信されます。このセッションクッキーの値を調べることでアプリケーションはその利用者がすでにログイン済みであることを判断し、利用者は毎回ログインし直す必要がなくなります。CSRFはこれに付け込みます。もし利用者が別のサイトからリクエストを発生させても、ブラウザは保存されているすべてのセッションクッキーを一緒に送ります。つまり、攻撃者は自分を認証させるためにはただ有効なリクエストを組み立て、被害者のブラウザにそれを実行させるだけでいいのです。

もし対象のサイトがCSRF対策をしていない場合、そのリクエストは通常のリクエストとして扱われます。攻撃者はパスワードを更新し、アカウントを削除し、他にも悪意のある行動ができてしまいます。

・RailsのCSRF対策

最初からApplicationControllerに以下の行が用意されています。

protect_from_forgery with: :exception

これはRailsが生成するすべてのフォームやAjaxリクエストで自動的にセキュリティトークンを含めるものです。もしセキュリティトークンが想定されている値と一致しなければ、例外(エラー)が投げられます。

基本的にはprotect_from_forgeryを上書きしたりApplicationControllerから削除しなければ、何も気にする必要はありません。

・AjaxとJavaScript

すべてのRails 5アプリケーションには、csrf_meta_tagsというメソッドがapp/view/layouts/application.html.erbにあります。

RailsのjQueryはPOST送信時にこのメソッドで追加されるHTMLタグの情報を自動的に使用するため、このメソッドがあれば特に何もせずともCSRF対策がなされます。細かい動きについては元ブログを参照ください。

・API

APIはステートレスであるべきなので、認証はすべてのリクエストでサーバー側のセッションを使わずに行われます。ですのでAPIのコントローラにはprotect_from_forgeryを追加したくないでしょうし、実際CSRF攻撃のリスクはほぼありません。

Rails 5ではAPIオンリーのアプリケーションを作成できます。デフォルトではAPIオンリーのアプリケーションはActionController::BaseではなくActionController::APIを継承し、ActionController::APIはprotect_from_forgeryを実行しません。このようにAPIオンリーのアプリケーションも特別な設定をせずに動作します。

—–

以上のように最初からセキュリティ対策が備えられているRails(CSRF対策だけでなくXSS対策もされています)は便利で安全ですが、どこでどのような対策をしているのかは知っておくべきだと思います。そうでないとアプリケーションが想定外の動きをした際の原因究明に時間がかかってしまうかもしれませんし、あるいは予想外のバグが発生してしまうかもしれません。ぜひXSS対策についても調べてみてください。それではまた。

※コラム原文は以下をご覧ください。

http://kadwill.com/csrf-protection-in-rails/