web-dev-qa-db-ja.com

安全なREST内のAPI Ruby on Rails

REST作業中のプロジェクト用のAPIの構築を開始しました。RoRを使用してAPIを構築するための最良の方法について少し調査するようになりました。私はデフォルトでは、モデルは世界中に公開されており、URLの最後に ".xml"を配置して適切なパラメーターを渡すだけで、URLを介して呼び出すことができることをすぐに確認してください。

それで、次の質問が来ました。不正な変更を防ぐためにアプリを保護するにはどうすればよいですか?いくつかの調査を行っているときに、attr_accessibleおよびattr_protectedとその使用方法。これらについて話していることがわかった特定のURLは、2007年5月に投稿されました( here )。

Rubyのすべてのものと同様に、それ以来、物事は進化していると確信しています。だから私の質問は、これがRoR内でREST APIを保護するための最良の方法ですか?

そうでない場合、「新しいプロジェクト」または「既存のプロジェクト」のシナリオで何を提案しますか?

65
Levi Rosol

APIリクエストの認証にはいくつかのスキームがあり、それらはrestful_authenticationやacts_as_authenticatedのようなプラグインによって提供される通常の認証とは異なります。最も重要なのは、クライアントがセッションを維持しないため、ログインの概念がないことです。

HTTP認証

基本的なHTTP認証を使用できます。このため、APIクライアントは通常のユーザー名とパスワードを使用し、次のようにURLに配置します。

http://myusername:[email protected]/

私はrestful_authenticationがデフォルトでこれをサポートしていると信じているので、誰かがAPIまたはブラウザーを介してアプリを使用しているかどうかは無視できます。

ここでの1つの欠点は、すべてのリクエストでユーザー名とパスワードを平文で入力するようユーザーに要求していることです。 SSL経由でそれを行うことにより、これを安全にすることができます。

ただし、これを使用するAPIを実際に見たことはないと思います。特に現在の認証スキームではそのまま使用できるため、問題は何なのかわかりません。

APIキー

API認証を有効にするもう1つの簡単な方法は、APIキーを使用することです。これは基本的にリモートサービスのユーザー名です。誰かがあなたのAPIを使用するためにサインアップするとき、あなたは彼らにAPIキーを与えます。これは、リクエストごとに渡す必要があります。

ここでの欠点の1つは、誰かが他の誰かのAPIキーを取得した場合、そのユーザーとしてリクエストを作成できることです。すべてのAPIリクエストでHTTPS(SSL)を使用することで、このリスクをある程度相殺できると思います。

別の欠点は、ユーザーがどこに行っても同じ認証資格情報(APIキー)を使用することです。 APIクライアントへのアクセスを取り消す場合、唯一の選択肢はAPIキーを変更することです。これにより、他のすべてのクライアントも無効になります。これは、ユーザーが複数のAPIキーを生成できるようにすることで軽減できます。

APIキー+秘密キーの署名

非推奨(一種)-以下を参照OAuth以下

非常に複雑なのは、秘密鍵でリクエストに署名することです。これは、Amazon Web Services(S3、EC2など)が行うことです。基本的に、ユーザーに2つのキーを与えます。APIキー(つまり、ユーザー名)と秘密キー(つまり、パスワード)です。 APIキーはリクエストごとに送信されますが、秘密キーは送信されません。代わりに、通常は別のパラメーターを追加して、各要求に署名するために使用されます。

IIRC、Amazonは、リクエストにすべてのパラメーターを取り、パラメーター名でそれらを順序付けることによってこれを実現します。次に、ユーザーの秘密鍵をハッシュキーとして使用して、この文字列がハッシュされます。この新しい値は、送信される前に新しいパラメーターとして要求に追加されます。アマゾン側では、彼らは同じことをします。それらはすべてのパラメーター(署名を除く)を取り、それらを順序付け、秘密鍵を使用してハッシュします。これが署名と一致する場合、彼らは要求が正当であることを知っています。

ここでの欠点は複雑さです。このスキームを正しく機能させることは、API開発者とクライアントの両方にとって苦痛です。物事を機能させることができないクライアント開発者からの多くのサポート呼び出しと怒っている電子メールを期待してください。

OAuth

鍵と秘密の署名によるいくつかの複雑な問題に対処するために、 OAuth と呼ばれる標準が登場しました。コアOAuthは、キー+シークレット署名の一種ですが、その多くは標準化されており、 多くの言語のライブラリ に含まれています。

一般に、独自のキー/署名システムを作成するよりも、APIプロデューサーとコンシューマーの両方でOAuthを使用する方がはるかに簡単です。

また、OAuthは本質的にアクセスをセグメント化し、APIコンシューマーごとに異なるアクセス資格情報を提供します。これにより、ユーザーは他の消費アプリケーションに影響を与えることなく、選択的にアクセスを取り消すことができます。

特にRubyの場合、 OAuth gem があり、OAuthのプロデューサーとコンシューマーの両方にすぐにサポートを提供します。私はこのgemを使用してAPIを構築し、OAuth APIを消費しました。非常に感銘を受けました。アプリケーションにOAuthとは対照的に、より単純なAPIキースキーム)の場合、OAuth gem。

102
Micah

不正な変更を防ぐためにアプリを保護するにはどうすればよいですか?

attr_accessibleおよびattr_protectedは、どちらもActiveRecordモデルで一括割り当てを実行する機能を制御するのに役立ちます。あなたは間違いなくattr_protectedを使ってフォームインジェクション攻撃を防ぎたいです。 attr_protectedを使用するか、ハッキングします を参照してください。

また、Railsアプリのコントローラに誰もアクセスできないようにするために、ほぼ確実に何らかの種類のユーザー認証システムが必要で、before_filterをコントローラーに追加して、リクエストされたコントローラーアクションの実行を許可する前に、承認されたユーザーがリクエストを行っていることを確認します。

Ruby on Rails Security Guide (Rails Documentation Project)の一部)をご覧ください。

7
Gabe Hollombe

RESTアプリケーション用のRailsアプリケーション用のAPIも作成しているため、現時点では同様の質問に直面しています。

ユーザーが編集できる属性のみがattr_accessibleでマークされていることを確認することをお勧めします。これにより、update_attributesを使用して割り当てることができる属性のホワイトリストが設定されます。

私がしていることは次のようなものです:

   class Model < ActiveRecord::Base  
       attr_accessible nil  
   end

私のモデルはすべてそれを継承しているため、一括割り当て可能にしたいすべてのフィールドに対してattr_accessibleを定義する必要があります。個人的には、この動作をデフォルトで有効にする方法があったらいいのにと思います(存在する可能性があり、私はそれについて知りません)。

REST apiを使用するだけでなく、通常のフォームポストを使用することもできます。

3
jonnii

自分で多くのものを構築する手間を省く別のアプローチは、個々の開発者のキー、トークン、割り当てなどを処理する http://www.3scale.net/ のようなものを使用することです。また、分析を行い、開発者ポータルを作成します。

Ruby/Railsプラグイン Ruby APIプラグイン があり、トラフィックが到着したときにポリシーに適用されます oAuth gem と組み合わせて使用​​できます。また、アプリの前にワニスをドロップし、varnish lib mod: Varnish API Module を使用して使用することもできます。

0
steve