web-dev-qa-db-ja.com

Rails CSRF保護を無効にしないAPI設計

2011年2月に戻って、Railsが allnon-GETのCSRFトークンが必要)に変更されました リクエスト(APIエンドポイントのリクエストも含む)これがブラウザリクエストの重要な変更である理由の説明は理解していますが、そのブログ投稿では、APIが変更を処理する方法についてのアドバイスは提供されていません。

特定のアクションでCSRF保護を無効にすることに興味はありません。

APIはこの変更にどのように対処するべきですか? APIクライアントがAPIにGETリクエストを発行してCSRFトークンを取得し、そのセッション中のすべてのリクエストにそのトークンを含めることを期待していますか?

トークンは1つのPOSTから別のトークンに変更されないようです。セッションの期間中、トークンが変更されないと想定しても安全ですか?

セッションの有効期限が切れたときの余分なエラー処理は好みませんが、すべてのPOST/PUT/DELETE要求の前にトークンを取得する必要があるよりはましだと思います。

44
Steve Madsen

古い質問ですが、セキュリティは非常に重要なので、完全な答えに値すると思います。これで説明したように、 質問 APIを使用しても、CSRFのリスクがまだあります。はい、ブラウザはデフォルトでこれを防ぐことが想定されていますが、ユーザーがインストールしたブラウザとプラグインを完全に制御することはできないため、APIでCSRFから保護することがベストプラクティスと見なされます。

HTMLページ自体からCSRFメタタグを解析するのが時々見られた方法です。今日は単一のページ+ APIアプリの多くが機能する方法にうまく適合せず、HTML、JSON、XMLのいずれであるかに関係なく、すべてのリクエストでCSRFトークンを送信する必要があると感じています。

したがって、代わりに、すべてのリクエストのafterフィルターを介して、CSRFトークンをCookieまたはヘッダー値として渡すことをお勧めします。 RailsがすでにチェックしているX-CSRF-Tokenのヘッダー値として、APIは単純にそれを再送信できます。

これは私がAngularJSでそれをした方法です:

  # In my ApplicationController
  after_filter :set_csrf_cookie

  def set_csrf_cookie
    if protect_against_forgery?
      cookies['XSRF-TOKEN'] = form_authenticity_token
    end
  end

AngularJS 自動的にcookieを探すXSRF-TOKENという名前ですが、目的に合わせて自由に名前を付けてください。次に、POST/PUT/DELETEを送信するときに、Railsが自動的に検索するヘッダープロパティX-CSRF-Tokenを設定する必要があります。

残念ながら、AngualrJSはすでにXSRF-TOKEN Cookieをヘッダー値X-XSRF-TOKENで送り返しています。 Railsのデフォルトの動作をオーバーライドして、これをApplicationControllerに次のように収めることは簡単です。

  protected

  def verified_request?
    super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
  end

Rails 4.2の場合、使用する必要があるCSRFを検証するための組み込みヘルパーがあります。

  protected

  def verified_request?
    super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
  end

お役に立てば幸いです。

編集: これについての議論Rails pull-request を提出しました私は、ログインのためにAPIを介してCSRFトークンを渡すことは特に悪い習慣であることが判明しました(たとえば、誰かがトークンの代わりにユーザーの資格情報を使用するサードパーティのログインをサイトに作成する可能性があります。そのため、アプリケーションを認証するかどうかを決めるのはあなた次第です。この場合でも、上記を使用できます。アプローチしますが、CSRF Coo​​kieは、すべてのリクエストに対してではなく、認証済みのセッションを持っているブラウザにのみ返信します。これにより、CSRFメタタグを使用せずに有効なログインを送信できなくなります。

48
Chris Nicola

Railsは「デフォルトでセキュア」な規則に従って動作します。クロスサイトまたはクロスセッションリクエストフォージェリでは、ユーザーにブラウザと別の信頼できるWebサイトが必要です。 APIはブラウザで実行されず、セッションを維持しないため、これはAPIには関係ありません。したがって、APIのCSRFを無効にする必要があります。

もちろん、あなたはshould HTTP認証またはカスタム実装されたAPIトークン、またはOAuthソリューションを要求することにより、APIを保護する必要があります。

6
Ariejan