it-roy-ru.com

AngularJS Web Api AntiForgeryToken CSRF

У меня есть одностраничное приложение AngularJS, размещенное в приложении ASP.NET MVC.
Серверная часть - это ASP.NET Web Api.

Я хотел бы защитить его от атак CSRF, сгенерировав AntiForgeryToken в части ASP.NET MVC, передать его в AngularJS, а затем проверить Web ApiAntiForgeryToken, полученный от последующих вызовов AngularJS.

«Подделка межсайтовых запросов (CSRF) - это атака, которая приводит к окончанию Пользователь может выполнять нежелательные действия в веб-приложении, в котором он находится в настоящее время аутентифицировано. CSRF-атаки специально направлены на запросы на изменение состояния, а не кража данных, так как злоумышленник не имеет способ увидеть ответ на поддельный запрос. С небольшой помощью социальная инженерия (например, отправка ссылки по электронной почте или в чате), Злоумышленник может обмануть пользователей веб-приложения при выполнении действия по выбору злоумышленника. Если жертва является обычным пользователем, a успешная атака CSRF может заставить пользователя выполнить изменение состояния запросы, такие как перевод средств, изменение адреса электронной почты и т. д. вперед. Если жертва является административной учетной записью, CSRF может скомпрометировать все веб-приложение. »
- Открытый проект безопасности веб-приложений (OWASP)

34
Mihai-Andrei Dinculescu

Добавьте к ASP.NET MVCView, который обслуживает AngularJS SPA, скажем, Views\Home\Index.cshtml, HTML-помощник, который генерирует AntiForgeryToken.

@Html.AntiForgeryToken();

Сконфигурируйте AngularJS, чтобы передать сгенерированный выше AntiForgeryToken как заголовок запроса.

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

Создайте пользовательский Web API Filter для проверки всех не-GET запросов (PUT, PATCH, POST, DELETE). 

Это предполагает, что все ваши запросы 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. Вы можете установить его через NuGet с помощью Install-Package Microsoft.AspNet.WebApi.Core.

Этот пост был сильно вдохновлен этот пост в блоге .

52
Mihai-Andrei Dinculescu

Добавить __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