web-dev-qa-db-ja.com

AngularJS Web Api AntiForgeryToken CSRF

AngularJSシングルページアプリケーション(SPA)がホストされていますASP.NET MVCアプリケーション。
バックエンドはASP.NET Web Apiです。

[〜#〜] csrf [〜#〜]攻撃から保護するために、ASP.NET MVC部分でAntiForgeryTokenを生成し、それをAngularJSに渡してから、Web Apiで後続のAngularJS呼び出しから受け取ったAntiForgeryTokenを検証します。

「クロスサイトリクエストフォージェリ(CSRF)は、エンドユーザーが現在認証されているWebアプリケーションで不要なアクションを実行するように強制する攻撃です。 CSRF攻撃は、攻撃者が偽造された要求に対する応答を確認する方法がないため、データの盗難ではなく、状態が変化する要求を特に対象としています。ソーシャルエンジニアリング(メールやチャットでリンクを送信するなど)の少しの助けを借りて、攻撃者はWebアプリケーションのユーザーをだまして攻撃者が選択したアクションを実行させることができます。被害者が通常のユーザーである場合、CSRF攻撃が成功すると、ユーザーに、資金の転送、電子メールアドレスの変更などの状態変更要求を実行させることができます。被害者が管理アカウントである場合、CSRFはWebアプリケーション全体を侵害する可能性があります。」
-オープンWebアプリケーションセキュリティプロジェクト(OWASP)

ASP.NET MVCViewに追加これはAngularJS SPAを提供します。たとえば、AntiForgeryTokenを生成するHTMLヘルパー__Views\Home\Index.cshtml_とします。

_@Html.AntiForgeryToken();
_

AngularJSを設定して、上記で生成されたAntiForgeryTokenRequest Headerとして渡します。

_angular.module('app')
.run(function ($http) {
    $http.defaults.headers.common['X-XSRF-Token'] =
        angular.element('input[name="__RequestVerificationToken"]').attr('value');
});
_

カスタムWeb API Filterを作成して、GET以外のすべてのリクエスト(PUTPATCHPOSTDELETE)。

これは、すべてのGET要求が安全であり、保護する必要がないことを前提としています。
そうでない場合は、if (actionContext.Request.Method.Method != "GET")除外を削除します。

_using System;
using System.Linq;
using System.Net.Http;
using System.Web.Helpers;
using System.Web.Http.Filters;

namespace Care.Web.Filters
{
    public sealed class WebApiValidateAntiForgeryTokenAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(
            System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (actionContext == null)
            {
                throw new ArgumentNullException("actionContext");
            }

            if (actionContext.Request.Method.Method != "GET")
            {
                var headers = actionContext.Request.Headers;
                var tokenCookie = headers
                    .GetCookies()
                    .Select(c => c[AntiForgeryConfig.CookieName])
                    .FirstOrDefault();

                var tokenHeader = string.Empty;
                if (headers.Contains("X-XSRF-Token"))
                {
                    tokenHeader = headers.GetValues("X-XSRF-Token").FirstOrDefault();
                }

                AntiForgery.Validate(
                    tokenCookie != null ? tokenCookie.Value : null, tokenHeader);
            }

            base.OnActionExecuting(actionContext);
        }
    }
}
_

_Global.asax.cs_で、新しく作成したフィルターをグローバルフィルターとして登録します。

_    private static void RegisterWebApiFilters(HttpFilterCollection filters)
    {
        filters.Add(new WebApiValidateAntiForgeryTokenAttribute());
    }
_

あるいは、このフィルターをグローバルに追加したくない場合は、次のような特定のWeb APIアクションにのみ配置できます

_[WebApiValidateAntiForgeryToken]
_

もちろん、属性を必要とするアクションに属性を適用することを忘れる可能性が常にあるため、これは定義上安全ではありません。

また、_Microsoft.AspNet.WebApi.Core_名前空間にアクセスするには、_System.Web.Http_パッケージが必要です。 _Install-Package Microsoft.AspNet.WebApi.Core_を指定してNuGet経由でインストールできます。

この投稿は このブログ投稿 から大きな影響を受けています。

__RequestVerificationTokenをFormDataに追加します

 var formData = new FormData();
    formData.append("__RequestVerificationToken", token);
    formData.append("UserName", $scope.kullaniciAdi);
    formData.append("Password", $scope.sifre);

    $http({
        method: 'POST',
        url: '/Login/Login',
        data: formData,
        transformRequest: angular.identity, 
        headers: { 'Content-Type': undefined }

    }).then(function successCallback(response) {



    }, function errorCallback(response) {

    });
0
Ufuk Aydın