1

I have a e-commerce Django application that automatically verifies all incoming POST requests with CSRF token using the CSRFViewMiddleware.

Now, for payments, I'm using a payment gateway where I pass the relevant details along with the csrfmiddlewaretoken so that it is returned back to me when the transaction on 3rd party site is complete. So, when the user is re-directed back to my site, I get a

403 Forbidden
CSRF verification failed. Request aborted.

How do I fix this? Is there any way I can manually check csrftoken using request.POST.get('csrfmiddlewaretoken') or something like that.

I would prefer not to bypass csrf totally as I want it to be secure (atleast, as much as possible).

Edit I understand csrfmiddleware token needs to be passed in the header but I cannot do that as there are only limited things I can do with a 3rd party payment gateway.

Gaurav Wadhwani
  • 1,352
  • 2
  • 15
  • 32
  • 2
    You should not be passing the CSRF token to third party sites. – Burhan Khalid Aug 12 '15 at 09:40
  • @BurhanKhalid fair enough. The thing is I have a couple of payment options where I process some options and the others are processed by a 3rd party site. How do I secure this process then?) – Gaurav Wadhwani Aug 12 '15 at 09:45
  • Unlike a human user, any half-decent external service cannot be tricked into sending a request to your site with information from a different site (the attacker). Most of them don't depend on cookies or sessions either, so CSRF attacks are inherently useless. You secure the request by whichever authentication mechanism the third-party service provides. – knbk Aug 12 '15 at 11:21
  • Ok, in that case, how do I disable `csrf` validation. I used `@csrf_exempt def post(self, request, *args, **kwargs):` but that did not help, i.e., still get a 403 Forbidden Error relating to csrf. – Gaurav Wadhwani Aug 12 '15 at 11:50
  • See [decorating class-based views](https://docs.djangoproject.com/en/1.8/topics/class-based-views/intro/#decorating-class-based-views). Decorating `post()` won't work in this case, you need to decorate `dispatch()` or the result of `as_view()`. – knbk Aug 12 '15 at 15:28

1 Answers1

2

From this snippet, I get a feeling that you may not quite understand what is CSRF:

I have a e-commerce Django application that automatically verifies all incoming POST requests with CSRF token using the CSRFViewMiddleware.

That's part your problem right there. CSRF is only for those requests that are made from your site, to your site (see OWASP's definition of CSRF):

Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user’s Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated.

You need CSRF tokens only on those forms that are generated by your site, and post to your site. In addition, any javascript code that sends a POST request should also be properly protected.

For all other end points - for example, if some payment provider is posting the result back to your application - you do not want to enable CSRF protection otherwise the requests will continue to fail.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • Yes. That clears my thought process. So I tried using @csrf_exempt over my post view that accepts post requests but I still get a 403 Csrf error. Any idea why? – Gaurav Wadhwani Aug 12 '15 at 12:41
  • `csrf_exempt` should prevent CSRF errors. If you are still getting errors, make sure that the exempt view is actually being called, and post the view. – Alasdair Aug 12 '15 at 14:15