Proposal: Make CSRF token validation for other HTTP Methods (PUT, PATCH, DELETE) The Same as POST

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Proposal: Make CSRF token validation for other HTTP Methods (PUT, PATCH, DELETE) The Same as POST

Osaetin Daniel
I came across this issue, because i'm building a SPA with Vue and Django Rest Framework as the backend.

I'm using SessionAuthentication Which requires that the CSRF token must be sent along with the data for HTTP methods that Change State on the Server if not the request would be flagged as invalid, for POST requests it's okay to send the CSRF token as part of the payload

e.g

{'foo': 'bar', 'csrfmiddlewaretoken': '....token'}

But for other requests this doesn't work and you're required to set the token in the request header to whatever
settings.CSRF_HEADER_NAME
 
is set to (By default it's "HTTP_X_CSRFTOKEN"). (This is what Django Rest Framework currently does through the browse-able API)

So i want to make a proposal to Elevate other HTTP methods, so the CSRF token can be sent directly with the payload as "csrfmiddlewaretoken" like you'll normally do for a POST request. The fallback to "settings.CSRF_HEADER_NAME" would remain so old code that depends on that behaviour does not break. This seems more consistent to me and also allows Django support two ways of sending the CSRF token. (Either through the header or in the payload directly)

This is the link to the concerned code in github https://github.com/django/django/blob/86de930f413e0ad902e11d78ac988e6743202ea6/django/middleware/csrf.py#L283-L303

If this is a terrible Idea, I would like to know why POST requests are the only methods that allows the CSRF token to be sent along with the payload directly instead of setting the token in the Header.

Thanks. 



--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ad22ae61-7249-4aa4-98ba-39cc95e8222b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Proposal: Make CSRF token validation for other HTTP Methods (PUT, PATCH, DELETE) The Same as POST

tom christie
> If this is a terrible Idea, I would like to know why POST requests are the only methods that allows the CSRF token to be sent along with the payload directly instead of setting the token in the Header.

That behaviour is because GET and POST are the only two methods supported by browsers for HTML form submission. In the case of standard HTML forms it's not possible to add extra headers, so the only way to include a CSRF token is to include it in the payload.

For any other method you'll necessarily be making an AJAX request (or some other programmatic interaction outside of a browser) in which case adding the CSRF token to the headers is possible, and preferable.

Reasons that you might not want to allow the CSRF token in the payload include:

* What do you do about non-form encoded payloads. Do you allow a CSRF token in JSON? What about JSON where the top level element isn't an object but is a list, or a primitive such as a number? What about other encoding such as YAML or XML?
* DELETE requests don't typically include request payloads. Clients may not handle payloads on DELETE and might coerce data to query parameters in that case. Servers and intermediaries might not rely payloads on DELETE requests to the application.

Another way around of expressing this is that we don't really want a CSRF token in the payload in any cases, it's just that the constraints of HTML forms in browsers means it's the only way we can do it there.

  - T :)

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/3b20b364-5ffb-4f63-9321-46b3b3633f70%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Make CSRF token validation for other HTTP Methods (PUT, PATCH, DELETE) The Same as POST

Osaetin Daniel
In reply to this post by Osaetin Daniel
Thanks, Tom Christie. Now i understand why.

On Saturday, May 6, 2017 at 11:49:57 PM UTC+1, Osaetin Daniel wrote:
I came across this issue, because i'm building a SPA with Vue and Django Rest Framework as the backend.

I'm using SessionAuthentication Which requires that the CSRF token must be sent along with the data for HTTP methods that Change State on the Server if not the request would be flagged as invalid, for POST requests it's okay to send the CSRF token as part of the payload

e.g

{'foo': 'bar', 'csrfmiddlewaretoken': '....token'}

But for other requests this doesn't work and you're required to set the token in the request header to whatever
settings.CSRF_HEADER_NAME
 
is set to (By default it's "HTTP_X_CSRFTOKEN"). (This is what Django Rest Framework currently does through the browse-able API)

So i want to make a proposal to Elevate other HTTP methods, so the CSRF token can be sent directly with the payload as "csrfmiddlewaretoken" like you'll normally do for a POST request. The fallback to "settings.CSRF_HEADER_NAME" would remain so old code that depends on that behaviour does not break. This seems more consistent to me and also allows Django support two ways of sending the CSRF token. (Either through the header or in the payload directly)

This is the link to the concerned code in github <a href="https://github.com/django/django/blob/86de930f413e0ad902e11d78ac988e6743202ea6/django/middleware/csrf.py#L283-L303" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fblob%2F86de930f413e0ad902e11d78ac988e6743202ea6%2Fdjango%2Fmiddleware%2Fcsrf.py%23L283-L303\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEwkXribZEpi7inf2QZ5sh8Q5Exxw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fblob%2F86de930f413e0ad902e11d78ac988e6743202ea6%2Fdjango%2Fmiddleware%2Fcsrf.py%23L283-L303\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEwkXribZEpi7inf2QZ5sh8Q5Exxw&#39;;return true;">https://github.com/django/django/blob/86de930f413e0ad902e11d78ac988e6743202ea6/django/middleware/csrf.py#L283-L303

If this is a terrible Idea, I would like to know why POST requests are the only methods that allows the CSRF token to be sent along with the payload directly instead of setting the token in the Header.

Thanks. 



--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/1aa5bbf2-dd6d-4f13-a607-22218468869d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.