Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having a POST'able API and Django's CSRF Middleware

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.

like image 779
T. Stone Avatar asked Mar 08 '10 22:03

T. Stone


People also ask

What is CSRF middleware?

The CSRF middleware and template tag provides easy-to-use protection against Cross Site Request Forgeries.

How does Django handle CSRF?

Django protects against CSRF attacks by generating a CSRF token in the server, send it to the client side, and mandating the client to send the token back in the request header. The server will then verify if the token from client is the same as the one generated previously; if not it will not authorise the request.

What is CSRF middleware in Django?

Django has a {% csrf_token %} tag that is implemented to avoid malicious attacks. It generates a token on the server-side when rendering the page and makes sure to cross-check this token for any requests coming back in. If the incoming requests do not contain the token, they are not executed.


2 Answers

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

like image 63
Brian Luft Avatar answered Oct 17 '22 19:10

Brian Luft


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

like image 27
Adam Spence Avatar answered Oct 17 '22 21:10

Adam Spence