web-dev-qa-db-ja.com

REST JSから使用されるAPIのセキュリティ

私は、クライアント(私のCDNに格納されている)にJavaScriptを提供し、スクリプトタグを介してそれをWebページにロードできるアプリケーションを開発しています。このJavaScriptはDOMのいくつかのチェックを行い、情報をREST私が提供するAPIに送信します(ユーザーの操作は必要ありません。これはバックグラウンドタスクです)。JavasScriptをWebページに導入したクライアント私のWebサイトにログインして、JavaScriptファイルを介して収集した統計を確認できます。

ここで関係するのは私が提供するスクリプトと私のREST APIだけなので、それを安全にする方法、またはどれだけ安全にできるかについて明確な考えはありません。いいえクライアントのバックエンドとmy REST APIが必要です(現時点では、セキュリティにまったくアクセスできない場合は確認する必要があります)の相互作用)トークンを配置できないことはわかっていますまたはJavaScriptファイルの資格情報です。私が持っている唯一のアイデアは、リクエストの「発生元」を確認し、それを再びホワイトリストとして検証することですが、Originもだまされる可能性があるかどうかはわかりません(実際にはだまされる可能性があると思います) )、したがって、適切なレベルのセキュリティに到達しないためのホワイトリストを維持する必要があることは、時間の浪費のようです。

他のサービス(Googleタグマネージャーやその他のSEOユーティリティなど)が意図的な詐欺を防ぐためにどのように機能するかを知っている人はいますか? APIにプッシュされたリクエストが正当であることをどのように確認しますか?

編集:私の現在のコンテキストは、JavaScriptとREST APIのみが関係していることです。それを安全にすることは不可能に思われます。安全にするために、どの手順に従う必要がありますか? -私のクライアントの終わりと公開/秘密鍵のペアを使用することは良いように見えますが、この方法でも、ユーザーのクライアントのWebサイトにログインして、サーバーへのリクエストを保護せずに公開しないようにする必要があります。正しい?

ありがとう!

3
Jordi

認証バックエンドを持つことができ、ユーザーは最初に認証を行い、トークンを取得して、後続のリクエストでトークンを使用する必要があります。

うまくいけば、ユーザーだけがサービスへの認証情報を持ち(例外として、パスワードが漏洩したユーザーは例外です)、APIを操作できるのは1人だけです。ただし、ボットの所有者が認証バックエンドを総当たりしないように、バックエンドでレート制限を採用する必要があります。

2
ThoriumBR

一般的に、Originヘッダーを信頼することはできません。ブラウザからのリクエストである場合、canOriginヘッダーを信頼できますが、悪意のある攻撃者が制御するクライアントを介してエンドポイントを直接使用している場合、 Originヘッダーは無意味です。したがって、それが役立つかどうかは状況に依存します。

最も簡単な方法は、誰もがAPIアクセスを保護するのと同じ方法です-ユーザーにAPIトークンを付与し、クライアントにページのロード時にJavaScriptを使用してAPIトークンを登録させます。あなたはしばしばこのようなものを見るかもしれません:

<script type="text/javascript" src="//awesome.service.com/js">
<script type="text/javascript">
    AwesomeService::SetPublicToken('THISISMYAUTHTOKENASSIGNEDBYYOURSYSTEM');
</script>

これで明らかに認証トークンが公開されました-クライアントのページを表示している誰もが自分のトークンを確認して盗むことができます。したがって、強調はパブリックトークンです。保護しようとしているものに応じて、さまざまなサービスがさまざまな方法でこの問題に対処します。最も一般的な解決策は、異なるセキュリティルールまたはオプションに関連付けられた異なる秘密鍵と公開鍵を使用することです。 2つの例を考えてみましょう:マッピングサービス(グーグルマップなど)とクレジットカードプロセッサです。

マッピングサービス

ブラウザで地図を描画するJavaScriptファイルを想像してみましょう。誰もがこのサービスに料金を支払っていることを確認できるように、クライアントを認証する必要があります。これは、単純な公開認証キーによって効果的に保護でき、クライアントが許可されたホストのリストを構成できるようにします。これは、API呼び出しがブラウザーで情報を表示するために使用される場合にのみ非常に役立つため、APIがブラウザーから呼び出されることを想定しているため、ホワイトリストドメイン名のリストに対してOriginヘッダーチェックを使用します。 (クライアントが提供)意図したとおりに使用されていることを確認します。これにより、公開鍵が新しいWebサイトにコピーされるだけでなく、誰かが無料でサービスを利用するために使用されることもなくなります。

ブラウザの外での使用に関しては、誰かが悪意のないことをする動機は本当にありません。確かに、誰かがあなたの公開トークンをコピーして、それを使用し、ホワイトリストに登録されたドメインからのふりをするAPI呼び出しを行うスクリプトを生成する可能性があります(ブラウザ以外のHTTPクライアントを使用すると、Originヘッダーを簡単に偽装できるため)。このマッピングサービスは、ブラウザに表示するマップを返すだけなので、メリットはありません。実際にそれを行う唯一の理由は、公開認証キーを盗んだビジネスが本当に嫌で、サービスに多額の請求をしたい場合です。おそらく最も一般的な攻撃ベクトルではありません。

したがって、この公開認証トークンとオリジンチェックのようなケースでは、ユースケースには十分すぎるほどです。

クレジットカードプロセッサ

あなたが本当に機密情報を持っているサービスを持っていると想像してください-クレジットカード!チェックアウトページを離れることなくPCIに準拠した方法(ストライプなど)で実行できるように、クライアントが便利なJavaScriptファイルを使用してクレジットカードトランザクションを処理できるようにしたいとします。ブラウザーでこれを行うにはこれが必要ですが、公開トークンとオリジンのチェックだけではもはや十分ではありません。 (Originスプーフィングを介した)APIへの直接アクセスにより、悪意のあるユーザーはAPIを使用して自分のクレジットカードを払い戻しし、クライアントのビジネスからお金を盗む可能性があります。

それで、あなたは何をしますか?安全なアクションをプライベート認証トークンで分離し、パブリック認証トークンのみがアクションをリクエストできるようにします。これらのアクションは、誰とも共有されていない秘密鍵を使用して、クライアントのサーバー自体からの別のAPI呼び出しを介して承認される必要があります。 Stripeの場合、次のようになります。

  1. エンドユーザーのブラウザのJavaScriptライブラリがクレジットカード情報を収集します
  2. エンドユーザーのブラウザーのJavaScriptライブラリが公開鍵を使用してCC情報をStripeに送信します
  3. Stripeは、それ自体では役に立たない使い捨ての「トランザクション」トークンを送り返します。
  4. エンドユーザーのブラウザーのJavaScriptが、ストライプサービスを使用している(たとえば)eコマースサイトに認証トークンを送信します
  5. Eコマースサイトは、追加のAPI呼び出しを直接送信して、プライベート認証トークンを使用する使い捨ての「トランザクション」トークンでストライプを作成し、対応するクレジットカードで実際に何をするかをストライプに指示します(請求、払い戻しなど)。

これは明らかにより複雑なフローですが、ブラウザの何も非公開ではなく、APIサービスの観点から見ている場合に実際にブラウザと通信していることを保証する方法がないため、機密API呼び出しを保護する必要があります。 。

私は例で答えていると思いますが、状況に大きく依存するので、包括的な答えを出すのは難しいです。サービスの詳細によって実際に実行する手順が決まりますが、クライアント側のJavaScriptだけが関与している場合、本当に機密性の高いサービスを実際に保護することはできません。繰り返しますが、その理由は、クライアント側のすべてが事実上公開情報であり、HTTPリクエストのすべての側面が偽装される可能性があるためです。

1
Conor Mancone