Open Closed

Couldn't validate antifogery token for post and get requests #2524


User avatar
0
Anjaneyulu created
  • ABP Framework version: v5.0.0
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no
  • Exception message and stack trace:
  • Steps to reproduce the issue:"
  1. Create a project

  2. Added Validate anitforgery token middleware in .Web project like this

public class ValidateAntiForgeryTokenMiddleware { private readonly RequestDelegate _next; private readonly IAntiforgery _antiforgery;

    public ValidateAntiForgeryTokenMiddleware(RequestDelegate next, IAntiforgery antiforgery)
    {
        _next = next;
        _antiforgery = antiforgery;
    }

    public async Task Invoke(HttpContext context)
    {
        if (HttpMethods.IsPost(context.Request.Method))
        {
           await _antiforgery.ValidateRequestAsync(context);
        }
        else if (HttpMethods.IsPut(context.Request.Method))
        {
            await _antiforgery.ValidateRequestAsync(context);
        }
        await _next(context);
    }
}
public static class ApplicationBuilderExtensions
{
    public static IApplicationBuilder UseAntiforgeryTokens(this IApplicationBuilder app)
    {
        return app.UseMiddleware<ValidateAntiForgeryTokenMiddleware>();
    }
}
  1. Added app.UseAntiforgeryTokens(); webmodule.

  2. Intercept the requests in burpsuite and remove request verification token in repeater, but still the response is perfect.

Please let us know how to implement validate antiforgery token for both post and get requests as well.


12 Answer(s)
  • User Avatar
    0
    EngincanV created
    Support Team .NET Developer

    Hi @Anjaneyulu, I think you don't need to create a manual Anti Forgery Token Middleware. Instead, you can define AbpAntiForgeryOptions to enable auto validation for GET requests.

    Configure<AbpAntiForgeryOptions>(options =>
    {
        //By default only POST requests auto validate anti forgery tokens.
        //In other word "GET", "HEAD", "TRACE" and "OPTIONS" HTTP methods are ignored.
        
        options.AutoValidateIgnoredHttpMethods.Remove("GET"); //auto validate for GET requests
        
    });
    
    

    See CSRF Anti Forgery documentation for more information

  • User Avatar
    0
    Anjaneyulu created

    Hi @Anjaneyulu, I think you don't need to create a manual Anti Forgery Token Middleware. Instead, you can define AbpAntiForgeryOptions to enable auto validation for GET requests.

    Configure<AbpAntiForgeryOptions>(options => 
    { 
        //By default only POST requests auto validate anti forgery tokens. 
        //In other word "GET", "HEAD", "TRACE" and "OPTIONS" HTTP methods are ignored. 
         
        options.AutoValidateIgnoredHttpMethods.Remove("GET"); //auto validate for GET requests 
         
    }); 
     
    

    See CSRF Anti Forgery documentation for more information

    Hi @EngincanV , I have configured as you said

    Configure<AbpAntiForgeryOptions>(options => { //By default only POST requests auto validate anti forgery tokens. //In other word "GET", "HEAD", "TRACE" and "OPTIONS" HTTP methods are ignored.

    options.AutoValidateIgnoredHttpMethods.Remove("GET"); //auto validate for GET requests });

    Im not receving any data in get request. Do i need to add anything else ?

  • User Avatar
    0
    EngincanV created
    Support Team .NET Developer

    When you enabled auto validation for GET requests, you need to pass the RequestVerificationToken header with your requests. Unless you'll get an HTTP 400 error. But if you're making your requests via Swagger you won't get that error because a request verification token is set on behalf of you in every request. (https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js#L25-L29)

    So try to send a request to one of your services via Postman or simply using a browser, you'll get the following error.

    You can generate and set the cookie for your requests, useIAbpAntiForgeryManager.SetCookie() method.

  • User Avatar
    0
    Rajasekhar created

    How to pass the RequestVerificationToken module level (globally for all get requests)

  • User Avatar
    0
    EngincanV created
    Support Team .NET Developer

    Then you can create a middleware as below and get the generated cookie and pass it to the RequestVerificationToken header.

    P.S. If your GET requests don't change the state (and it shouldn't in most cases), you don't need to add anti-forgery token validation, in my opinion.

    public class SetRequestVerificationHeaderMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IAbpAntiForgeryManager _abpAntiForgeryManager;
    
        public ValidateAntiForgeryTokenMiddleware(RequestDelegate next, IAbpAntiForgeryManager abpAntiForgeryManager)
        {
            _next = next;
            _abpAntiForgeryManager = abpAntiForgeryManager;
        }
    
        public async Task Invoke(HttpContext context)
        {
            if (HttpMethods.IsGet(context.Request.Method))
            {
               var antiForgeryToken = await _abpAntiForgeryManager.GenerateToken();
               context.Request.Headers["RequestVerificationToken"] = antiForgeryToken;
            }
            
            await _next(context);
        }
    }
    
    //use middleware
    app.UseMiddleware<SetRequestVerificationHeaderMiddleware>();
    
    
  • User Avatar
    0
    Anjaneyulu created

    Then you can create a middleware as below and get the generated cookie and pass it to the RequestVerificationToken header.

    P.S. If your GET requests don't change the state (and it shouldn't in most cases), you don't need to add anti-forgery token validation, in my opinion.

    public class SetRequestVerificationHeaderMiddleware 
    { 
        private readonly RequestDelegate _next; 
        private readonly IAbpAntiForgeryManager _abpAntiForgeryManager; 
     
        public ValidateAntiForgeryTokenMiddleware(RequestDelegate next, IAbpAntiForgeryManager abpAntiForgeryManager) 
        { 
            _next = next; 
            _abpAntiForgeryManager = abpAntiForgeryManager; 
        } 
     
        public async Task Invoke(HttpContext context) 
        { 
            if (HttpMethods.IsGet(context.Request.Method)) 
            { 
               var antiForgeryToken = await _abpAntiForgeryManager.GenerateToken(); 
               context.Request.Headers["RequestVerificationToken"] = antiForgeryToken; 
            } 
             
            await _next(context); 
        } 
    } 
     
    //use middleware 
    app.UseMiddleware<SetRequestVerificationHeaderMiddleware>(); 
     
    

    We have added this configuration, but when we remove the request verification token from requests, response is still perfect. Are we missing something ? Please guide.

  • User Avatar
    0
    EngincanV created
    Support Team .NET Developer

    Hi @Anjaneyulu, you're not sending requests via Swagger right?

  • User Avatar
    0
    Anjaneyulu created

    Hi @Anjaneyulu, you're not sending requests via Swagger right?

    No. Actually we are intercepting the get request in burpsuite , removing the request verification token and forwarding the request to server. Should we consider burpsuite interpection as a swagger or postman request? I'm not sure.

  • User Avatar
    0
    EngincanV created
    Support Team .NET Developer
    Configure<AbpAntiForgeryOptions>(options =>
    {
        options.AutoValidateIgnoredHttpMethods.Remove("GET"); //auto validate for GET requests
    });
    

    After I've configured the AbpAntiForgeryOptions as above, I could not send a successful GET request to my endpoints unless I provide a RequestVerificationToken header.

    But if there is an interceptor and passes a RequestVerificationToken on behalf of me, I can successfully make a GET request as follow. (And we do it on Swagger UI)


    So can you try to navigate the URL of one of your GET requests on the browser? I am not sure but "burpsuite" might be intercepting the request and passing the RequestVerificationToken automatically (maybe you can check the header that it passed).

  • User Avatar
    0
    Anjaneyulu created
    Configure<AbpAntiForgeryOptions>(options => 
    { 
        options.AutoValidateIgnoredHttpMethods.Remove("GET"); //auto validate for GET requests 
    }); 
    

    After I've configured the AbpAntiForgeryOptions as above, I could not send a successful GET request to my endpoints unless I provide a RequestVerificationToken header.

    But if there is an interceptor and passes a RequestVerificationToken on behalf of me, I can successfully make a GET request as follow. (And we do it on Swagger UI)


    So can you try to navigate the URL of one of your GET requests on the browser? I am not sure but "burpsuite" might be intercepting the request and passing the RequestVerificationToken automatically (maybe you can check the header that it passed).

    Thanks. I will check and Let you know

  • User Avatar
    0
    Anjaneyulu created
    Configure<AbpAntiForgeryOptions>(options => 
    { 
        options.AutoValidateIgnoredHttpMethods.Remove("GET"); //auto validate for GET requests 
    }); 
    

    After I've configured the AbpAntiForgeryOptions as above, I could not send a successful GET request to my endpoints unless I provide a RequestVerificationToken header.

    But if there is an interceptor and passes a RequestVerificationToken on behalf of me, I can successfully make a GET request as follow. (And we do it on Swagger UI)


    So can you try to navigate the URL of one of your GET requests on the browser? I am not sure but "burpsuite" might be intercepting the request and passing the RequestVerificationToken automatically (maybe you can check the header that it passed).

    After adding this configuration we are not getting data for our Get request : -

    Configure<AbpAntiForgeryOptions>(options => { options.AutoValidateIgnoredHttpMethods.Remove("GET"); //auto validate for GET requests });


    But Adding this middleware , we are getting data but intercepting through burpsuite , removing request verification token and forwarding request is working fine.

    public class SetRequestVerificationHeaderMiddleware { private readonly RequestDelegate _next; private readonly IAbpAntiForgeryManager _abpAntiForgeryManager;

    public ValidateAntiForgeryTokenMiddleware(RequestDelegate next, IAbpAntiForgeryManager abpAntiForgeryManager)
    {
        _next = next;
        _abpAntiForgeryManager = abpAntiForgeryManager;
    }
    
    public async Task Invoke(HttpContext context)
    {
        if (HttpMethods.IsGet(context.Request.Method))
        {
           var antiForgeryToken = await _abpAntiForgeryManager.GenerateToken();
           context.Request.Headers["RequestVerificationToken"] = antiForgeryToken;
        }
        
        await _next(context);
    }
    

    }

    //use middleware app.UseMiddleware<SetRequestVerificationHeaderMiddleware>();

    Even Im not sure how burpsuite works.

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    What is the point of using Antiforgery token for GET Requests? You should never change your application state in GET Requests anyway.

    You are adding extra overhaul to your application. Although, if you have to put XSRF/CSRF protection for your GET request in your application it means you have bigger problems in your design.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11