web-dev-qa-db-ja.com

REST AP​​I呼び出しを保護するにはどうすればよいですか?

私はバックエンドで人気のあるWebフレームワークを使用する安らかなWebアプリを開発しています(Rails、sinatra、flask、express.js)。理想的には、Backbone.jsを使用してクライアント側を開発します。 javascriptクライアント側だけがこれらのAPI呼び出しと対話できるようにするにはどうすればよいですか?これらのAPI呼び出しをパブリックにして、curlによって、または単にブラウザーにリンクを入力することによって呼び出されるのは望ましくありません。

80
knd

最初の原則として、APIがJSクライアントによって消費される場合、それはパブリックであると想定する必要があります。単純なJSデバッガーは、攻撃者を特定の位置からバイト単位で同一のリクエストを送信できる位置に配置します。彼が選んだ道具。

つまり、あなたの質問を正しく読んだ場合、これはあなたが避けたいことではありません:あなたが本当にしたくないことは、あなたのAPIがJSクライアントに関与することなく(定期的に)消費されるということです。実施しない場合、少なくともクライアントの使用を推奨する方法に関するアイデアを次に示します。

  • APIには何らかの認証フィールド(たとえば、クライアントで計算されたハッシュ)があると確信しています。そうでない場合は、 This SO question をご覧ください。 sessionベース(a.o.t.ハードコーディング)でJSクライアントに提供されるソルト(またはAPIキー)を使用するようにしてください。このようにして、APIの無許可の消費者はより多くの作業を余儀なくされます。

  • JSクライアントの読み込み時に、いくつかのHTTPヘッダー(ユーザーエージェントが思い浮かぶ)とIPアドレスを覚えて、変更された場合は再認証を要求し、通常の容疑者のブラックリストを使用します。これにより、攻撃者は宿題をより徹底的にやり直す必要があります。

  • サーバー側では、最後のいくつかのAPI呼び出しを覚えておいて、別のAPI呼び出しを許可する前に、ビジネスロジックが新しい呼び出しをすぐに許可するかどうかを今すぐ確認してください。他の手段と組み合わせることで、これにより悪用者が簡単に検出できるようになります。

私はそれを必要な明確さで言っていないかもしれません:私はそれを不可能とみなし、悪用者があなたのサービスを消費することを完全に不可能にするそれはとても難しい、それは面倒の価値がないかもしれません。

80
Eugen Rieck

何らかの認証システムを実装する必要があります。これを処理する良い方法の1つは、予想されるヘッダー変数を定義することです。たとえば、セッショントークンを返す認証/ログインAPIコールを使用できます。 APIへの後続の呼び出しでは、 'your-api-token'のような特定の名前でHTTPヘッダー変数にセッショントークンが設定されることが期待されます。

あるいは、多くのシステムは、何らかの種類のapiアカウントシステムを使用して、予期されるアクセストークンまたはキー(youtube、facebook、Twitterなど)を作成します。これらの場合、クライアントはこれらを何らかの方法でクライアントに保存する必要があります。

次に、セッションのチェックをRESTフレームワークに追加し、例外をスローするだけです。可能な場合は、ステータスコード(安らぎのため)は401エラーになります。

10
gview

現在「JSON Web Token」と呼ばれるオープンスタンダードがあり、

https://jwt.io/ および https://en.wikipedia.org/wiki/JSON_Web_Token を参照してください

JSON Web Token(JWT)は、いくつかのクレームをアサートするトークンを作成するためのJSONベースのオープンスタンダード(RFC 7519)です。たとえば、サーバーは「adminとしてログイン」というクレームを持つトークンを生成し、それをクライアントに提供できます。クライアントはそのトークンを使用して、管理者としてログインしていることを証明できます。トークンはサーバーのキーによって署名されているため、サーバーはトークンが正当であることを確認できます。トークンは、特にWebブラウザーのシングルサインオン(SSO)コンテキストで、コンパクトでURLセーフで使用できるように設計されています。 JWTクレームは、通常、認証されたユーザーのIDをIDプロバイダーとサービスプロバイダー間で渡すために使用できます。または、ビジネスプロセスで必要とされる他のタイプのクレームもあります。[1] [2]トークンは認証および暗号化することもできます。[3] [4]

6
bbozo

@MarkAmeryとEugene、すみませんが、それは間違っています。

ブラウザで実行中のjs + html(クライアント)アプリは、次のようにnauthorized APIへの直接呼び出しを除外するように設定できます。

  1. 最初のステップ:認証を要求するようにAPIをセットアップします。 クライアントは最初にサーバー(または他のセキュリティサーバー)を介して自身を認証する必要がありますたとえば、正しいパスワードを入力するようにユーザーに要求します。

認証の前にAPIへの呼び出しは受け入れられません。

認証中に「トークン」が返されます。

認証後、認証「トークン」を持つAPI呼び出しのみが受け入れられます。

もちろん、この段階では、パスワードを持っている承認済みユーザーのみがAPIにアクセスできますが、アプリをデバッグするプログラマーであれば、テスト目的で直接アクセスできます。

  1. 2番目のステップ:ここで、追加のセキュリティAPIをセットアップします。これは、クライアントjs + htmlアプリがサーバーから最初に要求された後、短い時間内に呼び出されます。この「コールバック」は、クライアントが正常にダウンロードされたことをサーバーに伝えます。 REST AP​​I呼び出しを、クライアントが最近正常に要求された場合にのみ機能するように制限します。

APIを使用するには、まずクライアントをダウンロードして、実際にブラウザで実行する必要があります。コールバックを正常に受信し、短い時間内にユーザーがエントリした後のみ、APIは呼び出しを受け入れます。

したがって、これは資格情報のない無許可のユーザーである可能性があることを心配する必要はありません。

(質問のタイトルは、「REST AP​​I呼び出しをセキュリティで保護するにはどうすればよいですか?」むしろ誰が正しい?)

3
pashute

ここに私がやることがあります:

  1. X-APITOKENなどの呼び出しを使用して、HTTPヘッダーでAPIを保護します。

  2. PHPでセッション変数を使用します。ログインシステムを配置し、ユーザートークンをセッション変数に保存します。

  3. AjaxでPHPにJSコードを呼び出し、curlでセッション変数を使用してAPIを呼び出します。このように、セッション変数が設定されていない場合、セッション変数は呼び出されず、PHPコードにはAPIへのアクセストークンが含まれます。

0
Pavneet Singh
  1. クライアントが最初にindex.html(またはbackbone.jsなど)をロードするときに、サーバーにSESSION変数を設定します。

  2. すべてのAPI呼び出しでサーバー側でこの変数を確認します。

追伸これは「セキュリティ」ソリューションではありません!!!これは、サーバーの負荷を軽減して、他のWebサイトやアプリからAPIを乱用したり「ホットリンク」したりしないようにするためです。

0
Alex