web-dev-qa-db-ja.com

クロスドメインリクエストにcsrf保護を実装する方法

2つのWebアプリがあります。1つはAngularJSのWebUI用で、もう1つはJavaのREST Webサービス用です。どちらも別々のドメインにデプロイされています。

アプリケーションは認証にCookieを使用します。ユーザーが有効なユーザー名とパスワードを入力するたびに、サーバーはトークンを含むhttpのみのCookieを返し、そのCookieはすべてのリクエストに渡されます。両方のアプリでCORSを有効にしました。そのため、セッションCookieが正しく機能しています。

今、私はこれにCSRF保護を追加しようとしています。サーバーでcsrfcookie(httponlyではない)をREST応答の一部として送信し、UIがcookieから値を読み取り、それをaに渡すcsrfcookieを使用しようとしました。他のREST呼び出しのcsrfトークンヘッダー。

私が直面しているこのアプローチの問題は、サーバーが別のドメインにあるため、AngularJsの$ cookiesを使用してCookieを読み取ることができないことです。そのCookieの値を読み取る方法はありますか?そうでない場合、他の方法でCSRFを実装できますか?

また、ブラウザのWebUI自体にcsrfcookieの作成を実装しようとしましたが、ブラウザは別のドメインにあるため、CookieをWebサービスに送信しません。

だから、私の質問は、この種の状況にcsrf保護を実装する方法ですか?

17
user3565529

あなたはこれで正しい軌道に乗っていました:

また、ブラウザのWebUI自体にcsrfcookieの作成を実装しようとしましたが、ブラウザは別のドメインにあるため、CookieをWebサービスに送信しません。

CSRF Coo​​kieは、サーバーに「送信」されることを意図したものではなく、クライアントによって読み取られてから、カスタムHTTP要求ヘッダーで提供されることを意図しています。他のドメインからの偽造されたGETリクエスト(<img src="">などのHTMLタグによってトリガーされる)はカスタムヘッダーを設定できないため、これは、リクエストがドメインのjavascriptクライアントからのものであることを表明する方法です。

作業中のアイデアを実装する方法は次のとおりです。api.domain.comui.domain.comがあると想像してください。

1)ユーザーがAngularクライアントをui.domain.comからロードします

2)ユーザーが認証情報をAngularクライアントからapi.domain.comに投稿する

2)HttpOnlyと呼ばれるauthCookie認証Cookieと、カスタムヘッダー(例: X-Auth-Cookie。このヘッダーの値は、authCookieによって識別されるセッションにリンクされている一意の値です。

3)AngularクライアントはX-Auth-Cookieヘッダー値を読み取り、その値をそのドメインXSRF-TOKENui.domain.comCookieに保存します。

  • だから今あなたは持っています:

    • XSRF-TOKENui.domain.comcookie
    • api.domain.comauthCookie cookie

4)ユーザーがapi.domain.comで保護されたリソースをリクエストします。ブラウザは自動的にauthCookie値を提供し、Angularは自動的にX-XSRF-TOKENヘッダーを送信し、XSRF-TOKENcookieから読み取った値を送信します

5)サーバーは、X-XSRF-TOKENの値が、authCookieの値によって識別される同じセッションにリンクされていると主張します。

これがお役に立てば幸いです。 Angularのトークン認証についても書いています シングルページアプリ(SPA)のトークンベースの認証 (免責事項:私は Stormpath で働いています)

17
robertjd

AngularjsにはCSRFのサポートが組み込まれていますが、残念ながらクロスドメインでは機能しないため、独自にビルドする必要があります。

最初のリクエストでヘッダーとCookieにランダムなトークンを最初に返すことで、なんとか機能させることができました。ヘッダーを読み取るには、ヘッダーをAccess-Control-Expose-Headersに追加する必要があります。その後、これはすべての投稿に追加されます

$http.get('url').
    success(function(data, status, headers) {
        $http.defaults.headers.post['X-XSRF-TOKEN'] = headers('XSRF-TOKEN');
    });

次に、サーバー上でCookieの値をヘッダーの値と比較して、それらが同じであることを確認できます。

3
Wayne Ellery

$ http docs:Angularは、XSRFに対抗するメカニズムを提供します。XHRリクエストを実行する場合、クロスドメインリクエストには設定されません。

これは小さなライブラリをまとめたもので、役立つかもしれません https://github.com/pasupulaphani/angular-csrf-cross-domain

0
phani