I have AJAX code which makes POST requests to a Django 1.6.4 application. The view has CSRF protection enabled via the django.middleware.csrf.CsrfViewMiddleware. If I do not pass a cookie but do pass the HTTP_X_CSRFTOKEN, it fails.
I am looking at the code of django.middleware.csrf.CsrfViewMiddleware and I see that on line 161 it checks to see if if csrf_token is None: after getting it from the cookie. If it is None, it returns. Only afterwards does it check the csrfmiddlewaretoken param and the HTTP_X_CSRFTOKEN request header. This looks incorrect and the check for a missing csrf_token value should only be made after checking all the possible places for where it could be found.
Any one else had similar issues? Am I seeing this incorrectly?
I think the confusion might be that the CSRF cookie and the HTTP_X_CSRFTOKEN HTTP header exist on opposite sides of the comparison. In other words, to prevent CSRF attacks, Django compares:
CSRF cookie value vs. POST token value ("csrfmiddlewaretoken")
(or)
CSRF cookie value vs. HTTP header value ("HTTP_X_CSRFTOKEN")
That's why the cookie is always necessary. Using the HTTP_X_CSRFTOKEN header is a substitute for setting the token in POST data, not a substitute for the cookie.
If you are using jQuery you can create a beforeSend function that includes the csrf token. Django CSRF for more information.
Please be aware that Django looks for the Header X-CSRFToken not HTTP_X_CSRFTOKEN.
At least that was my problem during debugging of the code. (I also checked the django.middleware.csrf.CsrfViewMiddleware for this)
The if csrf_token is None is a extra check done by Django. (Stated from the comment in the if-statement.
No CSRF cookie. For POST requests, we insist on a CSRF cookie, and in this way we can avoid all CSRF attacks, including login CSRF.
I think (not sure) there is no single check to only validate the header from a ajax post request, and Django will do checks to prevent any form of CSRF attacks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With