32

I have a Django webapp that has both a front-end, web-accessible component and an API that is accessed by a desktop client. However, now with the new CSRF middleware component, API requests from the desktop client that are POST'ed get a 403.

I understand why this is happening, but what is the proper way to fix this without compromising security? Is there someway I can signal in the HTTP header that it's an API request and that Django shouldn't be checking for CSRF or is that a bad strategy?

Edit--

The method I'm using at the moment is that the desktop client sets a header, X-Requested-With: XMLHttpRequest. This is kinda hacky, but I'm not sure how this would be handled better.

T. Stone
  • 18,208
  • 15
  • 67
  • 95

3 Answers3

10

How about just splitting off a view(s) for your desktop client and decorating them with csrf_exempt?

FallenAngel
  • 15,966
  • 10
  • 78
  • 105
Brian Luft
  • 1,143
  • 8
  • 12
  • 6
    That is exactly the setup but `csrf_exempt` doesn't seem to make a difference. It still gives a 403 with that decorator. +1 because according to the doc this should be working, even though it's not. – T. Stone Mar 09 '10 at 00:41
  • 3
    This is ONLY valid if the API can't be accessed through the browser. Otherwise this is potentially super dangerous as a request could then be forged from another site, against the API. – Jonatan Littke May 21 '12 at 12:03
8

If you are using a Class Based View then you will need to csrf_exempt the dispatch method rather than the post method like this:

@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
    return super(MyView, self).dispatch(request, *args, **kwargs)

See this bug ticket: https://code.djangoproject.com/ticket/15794

Adam Spence
  • 2,412
  • 1
  • 18
  • 15
-3

Since Django 1.1, the CSRF code will automatically allow AJAX requests to pass through, since browsers seem to do proper security checks. Here is the original commit and the documentation.

Alex Morega
  • 3,786
  • 1
  • 20
  • 24
  • 2
    Hm, that's not true, is it? In the link you provided, it does say you need to add an extra header for AJAX to work, not that it works automatically. – Jonatan Littke May 21 '12 at 11:51