web-dev-qa-db-ja.com

RESTベースのAPIのCORSおよびCSRF防止

私は現在、CSRFを防ぐ方法に頭を抱えています。

私の最初の解決策は、どこでも提案されているトークンを使用することでした。もちろん、この問題は修正されます。

<img src="http://api.example.com/me/delete">

しかし、私が頭を動かせないのはそれです。

GET http://api.example.com/me/delete

有効なトークンがそのリクエストと一緒に送信されなかったため、実際には失敗しますが、攻撃者が上記を行うのを防ぎ、代わりに次のことを行うだけです

GET http://api.example.com/me/token/generate
// parse the response
GET http://api.example.com/me/delete?token=...

リクエストに沿って有効なトークンが渡され、ユーザーが削除されました...


私のREST APIは、あらゆるリクエストの通過を許可します。

header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_Origin"]);

私が「必要とする」理由は、フォームとJavaScriptを通じてドメイン自体でREST APIを使用しているだけではありません。しかし、C++でcURLを使用してリクエストを行っています。

この場合のトークンが「安全な」ソリューションではない場合、安全で優れたソリューションは何でしょうか?

Spotifyのようなものはさらに何をしますが、どちらも「Web API」と音楽ソフトウェア自体を持っていますか?


また、これはかなりフェッチされていますが、APIへのアクセスを許可することはできますが、Originごとの認証がありますか?

つまり、 http://example.com がAPIに「ログイン」している場合でも、- http://some-other-website.com が(またはcURLを使用して要求する場合はさらに)。

「解決策」はOriginヘッダーを確認することですが、これははるかにフェッチされていますが、なりすましの可能性があります。

4
vallentin

Same Origin Policy は通常、シナリオの発生を防ぎます。

GET http://api.example.com/me/token/generate
// parse the response

ドメインへのリクエストを行うサードパーティドメインを介して応答を解析することはできません。ブラウザは通常、SOPのためにそれをブロックします。

通常は、同じ生成元のルールを緩和するために次の応答ヘッダーも追加したためです。

header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_Origin"]);

次の誤解の下で:

私が「必要とする」理由は、フォームとJavaScriptを介して、ドメイン自体でREST APIを使用しているだけではありません。しかし、C++でcURLを使用してリクエストを行っています。

このヘッダーは、cURLには影響しません。ヘッダーはブラウザでのみ解析され、SOPを実装します。これは、Webクライアントへの直接のリクエストを妨げるものではありません。

解決

あなたのapi.example.comドメイン、フロントエンドがユーザーのブラウザを使用してフロントエンドからリクエストを行うことのみを許可します。

Access-Control-Allow-Origin: example.com

あなたのexample.comサイト、すべてのAPI AJAXリクエストとともに次のヘッダーを送信します:

X-Requested-With: XMLHttpRequest

この情報については、この回答を参照してください 。簡単に言えば、このヘッダーはCORSが有効になっていないとドメイン間で送信できません。

リクエストの受信時にこのヘッダーが存在することをAPIバックエンドで確認してください。そうでない場合は、CSRF攻撃です。

CURLを使用したサーバー側リクエストで、ヘッダーを手動で追加するだけです。例えば.

X-Requested-With: cURL

存在することを確認しているので、これらのリクエストは成功します。

最後に、Cookieを使用して認証を追加します。ログインしたWebサイトのユーザーには、Cookieで送信できる認証チケットが必要です。また、バックエンドcURLリクエストで使用する認証チケットが必要です。これにより、許可なくAPIを使用することはできなくなります。許可レベルを使用してWebユーザーが実行できるアクションを制限することをお勧めします。そうしないと、cURLサーバーツールのみが実行すべき機能を悪意を持って実行しようとする可能性があります。

7
SilverlightFox

元の質問のシナリオを見ると、OAuth/JWTトークンが推奨されるアプローチだと思います。これらのシナリオでは、他のオリジンにAPIへのアクセスを許可しますが、許可されているリクエストのみを許可します。これは、クレームがトークンに追加されるときにJWTトークンがこのレベルのセキュリティを提供し、それらのクレームに基づいて承認フィルターを追加できる場所です。

同じOriginリクエストのみを許可し、ユーザー認証は許可せず、CSRFを防止したい場合は、検証フィルターを備えた偽造防止トークンが有効です。典型的なケースはお問い合わせフォームです。これについて詳しくは、angularjsアプリを使用した次の例をご覧ください。

http://www.ozkary.com/2016/03/web-api-anti-forgery-token-angularjs.html

それが役に立てば幸い。

1
ozkary

私はあなたの質問を理解したことを望みます。

最初の部分と同様に、通常、攻撃者はサーバーより別のオリジンを使用するため、ブラウザーは応答を読み取るを許可しないため、 'レスポンスを解析し、後続のリクエストでトークンを送信します。しかし、この保護を無駄にするすべての起源を明示的に許可しました。

また、生成されたトークンには明らかに何らかの認証が必要です。ユーザーAのトークンはユーザーBに対して有効ではないため、手動でトークンを送信しても無効になります。

2番目の部分、適切に実装されたトークンメカニズムがある場合、リクエストがどこから来たかに関係なく、トークンは悪意のあるアクティビティを防止します。

3番目の部分については、あなたの質問を正しく理解した場合:ブラウザーからの作業に関する限り、CORSでは、JavaScriptまたはクライアント側のコードを使用してOriginを設定することはできません。したがって、Originに特定の値が必要なCSRF攻撃の場合、JavaScriptを使用して攻撃者はスプーフィングできませんその値です。

お役に立てば幸いです。

1
racec0ndition