skip to Main Content

How can i use an Antiforgery Token in ASP.NET Core 6 Web API with an extern consumer like a iOS or Android App? I don’t need user authentication for the requests. The app is hosted on another domain.

I have developed an Web API with an Antiforgery Token (Followed this link) and ASP.NET 6 Razor Pages. All is working perfekt. But how can i develop an extern App that uses this Web API? The Problem, i have no idea how can i create the Antiforgery Token from the "external" App? How can i configure the App to use the Web API with the Antiforgery Token?

3

Answers


  1. it is not necessary to implement Anti-Forgery Token protection against CSRF Attacks when building an API because how APIs are built and intended to be used, they require different methods of protection like:

    • using API Keys.
    • using Basic Authentication.
    • using OpenID Connect.

    because the goal is to prevent malicious clients from calling our API, we need to validate the identity of the client app that performs the request to the API.

    and in order to perform a CSRF attack, one of the main conditions is to have a Cookie-based authentication session (have a look at this article where it explains in detail how CSRF attacks are performed), which is not the case with APIs.

    however, if you’re calling your API using Ajax from your website where the API is on the same origin as the website and you rely on Cookie to authenticate the user, it is possible to (and you should) integrate Anti-Forgery Token protection, you can check this Answer on StackOverflow for more details on how to implement it.

    but since you are going to call the API from an external app just go with one of the above methods.

    check this article on Microsoft docs for more details on CSRF Attacks and how Anti-Forgery Token protection is implemented.

    also, check this article from RedHat to get more information about API security.

    Login or Signup to reply.
  2. I don’t agree with the answer that "it is not necessary to implement Anti-Forgery Token protection against CSRF Attacks when building an API".

    There is still a risk that somehow intruder can force the client app to send a malicious request.


    To configure Anti-Forgery Protection in .NET Web API (without using MVC Views), you need to use the package Microsoft.AspNetCore.Antiforgery.

    Keep in mind that there are two tokens which are being validated: a Cookie Token and a Request Token (from an HTTP header).

    // Field
    IAntiforgery _antiforgery;
    
    var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
    

    As a result, tokens will contain the value:

    {
        "CookieToken": "CfDJ8JPuS3COPd9AmHCMBz_IFVdVzR8cfeD2or9v3qMLlWgRiN812hKbkh4o8TpYl4AdA3uJ3FeoY3eozx59q_uSnloXl80nLEd6twLzkDdn4AifcsGWcwaAxWSrGTui0vwl7-SHjftCfkbj9pAlDC_DS0Q",
        // Ignore this: built-in mechanism for forms
        "FormFieldName": "__RequestVerificationToken",
        "HeaderName": "X-XSRF-TOKEN",
        "RequestToken": "CfDJ8JPuS3COPd9AmHCMBz_IFVfnP50wBywG2WJmFoYA7nx-VGzBjPRY16-p3BBFRMUGHt4cz-M-VrZ_jX_7vUoIt0OX3xhHNw8swt0CebGa4P41cVej2F_DvvayOvrhbY6s3Z2U1aZWHmAvBT8NlH7ueRE"
    }
    

    Note that CookieToken and RequestToken are different.

    Cookie Token is handled automatically. But Request Token should be handled by us.

    1. Create a validation middleware:

      public class AntiforgeryMiddleware : IMiddleware
      {
          private readonly IAntiforgery _antiforgery;
      
          public AntiforgeryMiddleware(IAntiforgery antiforgery)
          {
              _antiforgery = antiforgery;
          }
      
          public async Task InvokeAsync(HttpContext context, RequestDelegate next)
          {
              var isGetRequest = string.Equals("GET", context.Request.Method, StringComparison.OrdinalIgnoreCase);
              if (!isGetRequest)
              {
                  await _antiforgery.ValidateRequestAsync(context);
              }
      
              await next(context);
          }
      }
      
    2. Configure DI in your Web API application:

      // Startup.cs
      public void ConfigureServices(IServiceCollection services)
      {
          // ...
      
          // Extension method comes from the `Microsoft.AspNetCore.Antiforgery` package
          services.AddAntiforgery(options =>
          {
              options.HeaderName = "X-XSRF-TOKEN";
          });
      
          services.AddScoped<AntiforgeryMiddleware>();
      }
      
    3. Configure a validation middleware:

      // Startup.cs
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
      {
          // ...
      
          app.UseMiddleware<AntiforgeryMiddleware>();
      
          app.UseEndpoints(endpoints =>
          {
              endpoints.MapControllers();
          });
      }
      
    4. Create a XSRF Token endpoint:

      [Route("api/xsrf-token")]
      [ApiController]
      public class AntiForgeryController : Controller
      {
          private IAntiforgery _antiforgery;
      
          public AntiForgeryController(IAntiforgery antiforgery)
          {
              _antiforgery = antiforgery;
          }
      
          [IgnoreAntiforgeryToken]
          public IActionResult Get()
          {
              // Creates and sets the cookie token in a cookie
              // Cookie name will be like ".AspNetCore.Antiforgery.pG4SaGh5yDI"
              var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
      
              // Take request token (which is different from a cookie token)
              var headerToken = tokens.RequestToken;
              // Set another cookie for a request token
              Response.Cookies.Append("XSRF-TOKEN", headerToken, new CookieOptions
              {
                  HttpOnly = false
              });
              return NoContent();
          }
      }
      
    5. On the client make a request to the URL /api/xsrf-token.

      Then read a request token cookie XSRF-TOKEN and set it to a X-XSRF-TOKEN HTTP header for non-GET requests:

      X-XSRF-TOKEN: <request-token>
      
    Login or Signup to reply.
  3. I was a security champion some time ago so know what is security (however recently not following the topic). But in every conference or training usually 2 things true:

    1. Security is hard to do right…
    2. Security is very very hard to do right… So NEVER do it yourself!!

    In your case the problem is that Antiforgery Token (CSRF protection) is not available in APIs. It is available in MVC only and for a good reason:

    • MVC is using session and form is rendered on the server, so token generated on server side, send to the HTML form and stored in the user session for POST back validation.
    • Most MVC sites are using Cookie based Auth which is affected by CSRF post attacks.
    • REST API should be stateless, it means by default no session. Response is not HTML but XML/JSON data. "Form" POST happens from other systems and secure way to expose Antiforgery token.
    • Most RestFul APIs are using oAuth2 or some Bearer token Auth which is NOT EVEN impacted by CSRF!!!

    So the answer is to your question another question. Do you use Cookie based Authorization in your API?

    If not then you should NOT use Antiforgery tokens it is NOT impacting your API… Otherwise you should switch to Bearer Auth headers and you are set.

    Also please ignore the coded answers because they have many issues. Implementation will compile, code runs for sure but full of security problems (Homebrew security). E.g. Token stored in Cookie which is the basic of CSRF attack Cookies attached by the browsers automatically to a request, GET method is secure and cannot even protected against, etc…

    Homebrew security can give false confidence (yes I "secured" it) is it secured?:

    Homebrew security failed...

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search