Mihai-Andrei Dinculescu Mihai-Andrei Dinculescu - 1 year ago 125
AngularJS Question

AngularJS Web Api AntiForgeryToken CSRF

I have an AngularJS Single Page Application (SPA) hosted by an ASP.NET MVC application.

The back-end is ASP.NET Web Api.

I would like to protect it against CSRF attacks by generating an

in the ASP.NET MVC part, pass it to AngularJS, and then have Web Api validate the
received from the subsequent AngularJS calls.

“Cross-Site Request Forgery (CSRF) is an attack that forces an end
user to execute unwanted actions on a web application in which they're
currently authenticated. CSRF attacks specifically target
state-changing requests, not theft of data, since the attacker has no
way to see the response to the forged request. With a little help of
social engineering (such as sending a link via email or chat), an
attacker may trick the users of a web application into executing
actions of the attacker's choosing. If the victim is a normal user, a
successful CSRF attack can force the user to perform state changing
requests like transferring funds, changing their email address, and so
forth. If the victim is an administrative account, CSRF can compromise
the entire web application.”

- Open Web Application Security Project (OWASP)

Answer Source

Add to the ASP.NET MVC View that serves the AngularJS SPA, let's say Views\Home\Index.cshtml, the HTML helper that generates the AntiForgeryToken.


Configure AngularJS to pass the above generated AntiForgeryToken as Request Header.

.run(function ($http) {
    $http.defaults.headers.common['X-XSRF-Token'] =

Create a custom Web API Filter to validate all non-GET requests (PUT, PATCH, POST, DELETE).

This assumes that all your GET requests are safe and don't need protecting.
If that's not the case, remove the if (actionContext.Request.Method.Method != "GET") exclusion.

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
                    .Select(c => c[AntiForgeryConfig.CookieName])

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

                    tokenCookie != null ? tokenCookie.Value : null, tokenHeader);


Register the newly created filter as a global one, in Global.asax.cs.

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

Alternatively, if you don't wish to add this filter globally, you can put it only on certain Web API actions, like this


This of course is by definition less secure, as there's always the chance that you'll forget to apply the attribute to an action that needs it.

This post has been heavily inspired by this blog post.