Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSRF validation failure when using "HTML Form" to POST #4471

Closed
5 of 6 tasks
skirsdeda opened this issue Sep 7, 2016 · 5 comments
Closed
5 of 6 tasks

CSRF validation failure when using "HTML Form" to POST #4471

skirsdeda opened this issue Sep 7, 2016 · 5 comments

Comments

@skirsdeda
Copy link

skirsdeda commented Sep 7, 2016

Checklist

  • I have verified that that issue exists against the master branch of Django REST framework.
  • I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
  • This is not a usage question. (Those should be directed to the discussion group instead.)
  • This cannot be dealt with as a third party library. (We prefer new functionality to be in the form of third party libraries where possible.)
  • I have reduced the issue to the simplest possible case.
  • I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.)

Steps to reproduce

  • POST using "HTML Form" to serializer which expects valid authenticated user.

Expected behavior

  • "HTML Form" should include "X-CSRFToken" header in the request so that authentication (just like "Raw data" tab does)

Actual behavior

  • Doesn't send "X-CSRFToken" header, CSRF validation silently fails and request.user becomes AnonymousUser although there is a valid authentication cookie (or whatever other means of authentication).

The culprit

rest_framework/static/rest_framework/js/ajax-form.js: lines 26-30:

  if (method === 'POST' && !contentType) {
    // POST requests can use standard form submits, unless we have
    // overridden the content type.
    return;
}

Since "HTML Form" doesn't override contentType, request is posted via Form (not AJAX) and "X-CSRFToken" is not added.
I think the aforementioned piece of code could be simply deleted unless anyone knows a good reason why it is necessary :)

@xordoquy
Copy link
Collaborator

xordoquy commented Sep 7, 2016

"POST using "HTML Form" to serializer which expects valid authenticated user."
Isn't it what the browsable API does already ? AFAIT it works.

@skirsdeda
Copy link
Author

skirsdeda commented Sep 7, 2016

@xordoquy Yes, I am talking about browsable API. The problem is that request.user is not determined correctly when "X-CSRFToken" is not sent. I am using session authentication in this case.

To put it simply, "Raw data" form works for me while "HTML Form" doesn't. And this is definitely because of the CSRF header.

@xordoquy
Copy link
Collaborator

xordoquy commented Sep 7, 2016

I'm puzzled. The HTML Form do work for me. How do I reproduce the issue ?

@skirsdeda
Copy link
Author

@xordoquy set DEFAULT_PERMISSION_CLASSES to ['rest_framework.permissions.IsAuthenticated'] and leave the default for DEFAULT_AUTHENTICATION_CLASSES. Then login with any user and try posting with HTML Form. You should get 403 forbidden response:

"detail": "CSRF Failed: CSRF token missing or incorrect."

@xordoquy
Copy link
Collaborator

xordoquy commented Sep 7, 2016

I just did that and it works without issues with:
Django==1.10.1
djangorestframework==3.4.6

I'm going to close this issue for now.
I'll reconsider once we can reproduce the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants