3

Ruby On Rails フレームワークには、Web サービス API を公開するサーバー アプリケーションの構築を容易にする機能が含まれています。たとえば、コントローラーは次のことを行います。

respond_to :html, :json, :xml

def show
  @thing = Thing.find(params[:id])
  respond_with @thing
end

...両方の Web ブラウザーの「表示」アクションを処理し、HTML を返します。また、このデータ形式を指定する要求に対して、項目「@thing」を JSON または XML としてレンダリングします。

この特定の例では、GET ベースの「表示」アクションには、特別なセキュリティ対策は含まれていません。上記と同様のケースを考えてみますが、'create' や 'update' などのアクション - (シミュレートされた) PUT または (実際の) POST リクエストによってアクティブ化されるものです。これで、CSRF 保護が機能します。

ここで残念なことに、Rails は、同じドメインの Web ページ内で実行される JavaScript コードからの「API 呼び出し」(非 HTML 形式の応答) に対処するように設計されているようです。 CSRF 保護は必須です。JavaScript コードは、Rails に含まれる魔法の「メタ」タグを探し、CSRF トークンを読み取り、サーバー上で POST ベースのアクションなどを呼び出す XHR 呼び出しでそれを送信できます。

しかし、外部の呼び出し元についてはどうでしょうか? Rails が Web サイトをサポートしているが、同じヘッドエンドと通信するネイティブの iOS または Android アプリを作成したい場合はどうなるでしょうか? そのアプリはサービス呼び出しを行っています - いいですよ、Rails はこれを簡単にします - しかし、CSRF トークンを持っていないため、サーバー上のデータを変更しようとすると失敗します。同じコントローラ コードが Web ブラウザと「純粋な API」クライアントを処理するため、CSRF 保護をバイパスすることはできません。

Rails および API 呼び出しに関する CSRF の問題に関連するすべての回答は、そのような場合に別のコントローラーを使用することを想定しているようです。しかし、それはばかげています-CSRFをバイパスする特別なコントローラーで一連のコードを複製しない限り、WebページのJavaScriptコードにのみ使用される場合、「アプリをサービスとして簡単に公開できるようにする」もののポイントは何ですか非 Web クライアントを許可するには? このような追加のコントローラーは、攻撃面を増やすだけです。

RailsアプリでCSRF保護に対処するための推奨される「正しい」パターンを知っている人はいますか? 「respond_with(...)」のような組み込みのものは、遍在するフィールドとしてCSRFトークンを含むJSON / XMLオブジェクトを常に生成するなど、何も役に立ちません。私が考えることができる最善の方法は、それを自分で行うことです。たとえば、「@thing」を次のようにレンダリングします。

{
  csrf: "abcdef...7890",
  object: { ...JSON representation of @thing... }
}

...しかし、これはちょっとしたハックのようで、非常に多くの作業が必要であり、すべてのリクエストで最新のトークンをアナウンスすることで、world+dog の CSRF をバイパスしているようです。もっと良い方法があるはずです:-)

4

1 に答える 1

0

うーん、ドキュメント はそれを言う

リクエスト偽造防止をオンにします。GET 以外の HTML/JavaScript リクエストのみがチェックされることに注意してください。

JSON および XML 応答の要求が既に csrf チェックされていないことを示唆していますが、それがあなたの目標だったと思いますか? しかし、実際にはそのように機能しませんか?

コントローラーでverify_authenticity_tokenをオーバーライドして、実際にいつ検証を実施するかについてカスタム ロジックを設定することもできます。これは、他の実際のワーカー メソッドを呼び出して検証を行い、検証されていない場合は応答する非常に単純なメソッドであるため、必要に応じて特定の状況でのみ検証チェックを実行するようにオーバーライドできます。または、上書きする代わりに、同じアイデアに基づいて独自の before_filter を作成し、独自の before_filter を呼び出します。ソースを見て、ほとんどすべてがbefore_filter としてprotect_from_forgery追加 します。verify_authenticity_tokenただし、これらのいずれかを行うと、将来的には前方互換性がある場合とない場合があります。

ああ、あなたがリンクしたメモが「すべての非GETリクエスト」に対してCSRF保護が行われていることを発表しているのを見たので、それがHTMLリクエスト専用であるというドキュメントは古くなっていると思います-しかし、それは私に考えさせます、理由は何でしたかその変化のために?(その発表は脆弱性の性質を正確に文書化したものではなく、私は差分を探しに行っていません)。何らかの方法でそれを元に戻し、XML/JSON リクエストの CSRF をチェックしないようにすることは確かに成功します。何も思いつきません。

于 2012-08-21T03:53:13.370 に答える