CSRF protection question

132 views
Skip to first unread message

James Roper

unread,
Aug 15, 2013, 8:21:17 AM8/15/13
to django-d...@googlegroups.com
Hi,

I'm a core dev on Play Framework, and I'm currently looking closely at our CSRF protection and making improvements, and so I'm looking carefully at what other frameworks do because when it comes to security, it's easy to miss something.

I'd like to get a better understanding of the reason behind why X-Requested-With is no longer supported in Django.  I've read about the vulnerability behind it:


What I don't understand is why this vulnerability required server side fixes.  It's clearly a client side vulnerability, here's the Firefox version of the vulnerability in the NVD:


It is clearly stated that the vulnerability is in Firefox, not on the server side.  Firefox has since fixed the issue.  The issue is also fixed in Chrome:


So what I don't understand is why Django and Rails both raced to fix this on the server side?  It makes it a pain in both frameworks to do AJAX calls, where X-Request-With was such a simple solution.  And now that clients are fixed, the server side fixes don't seem to be necessary anymore.  Is there something I've missed?

Also, was this ever really fixed in Django?  Rails stores the token in the session, but Django stores the token in a cookie.  But since the vulnerability allowed setting arbitrary headers, couldn't an attacker just set the Cookie header to set the token to be whatever they wanted, and submit a token in the form that matched?  I ask because Play has an option that allows storing the token in a cookie, and I'd like to fully understand what if any issues there are with that (I can see from the Django source code that mitm attacks with SSL are a big pain to deal with for one).

Thanks for your help,

James

Russell Keith-Magee

unread,
Aug 16, 2013, 9:56:15 PM8/16/13
to django-d...@googlegroups.com
On Thu, Aug 15, 2013 at 7:21 PM, James Roper <jro...@gmail.com> wrote:
Hi,

I'm a core dev on Play Framework, and I'm currently looking closely at our CSRF protection and making improvements, and so I'm looking carefully at what other frameworks do because when it comes to security, it's easy to miss something.

I'd like to get a better understanding of the reason behind why X-Requested-With is no longer supported in Django.  I've read about the vulnerability behind it:


What I don't understand is why this vulnerability required server side fixes.  It's clearly a client side vulnerability, here's the Firefox version of the vulnerability in the NVD:


It is clearly stated that the vulnerability is in Firefox, not on the server side.  Firefox has since fixed the issue.  The issue is also fixed in Chrome:


So what I don't understand is why Django and Rails both raced to fix this on the server side?  It makes it a pain in both frameworks to do AJAX calls, where X-Request-With was such a simple solution.  And now that clients are fixed, the server side fixes don't seem to be necessary anymore.  Is there something I've missed?

Yes. Firefox and Chrome have *subsequently* fixed the issue. But you have no control over user space, and you have absolutely no guarantee that *all* users are using fixed browsers. Users don't always update browsers when they're told to, even if you flash a "YOU ARE COMPROMISED! UPDATE!!1!" banner in front of them. There *were* compromised browsers in the wild, and we have no reason to believe that *every one of them* has been updated to remove the problem.

I completely agree that the AJAX hole was very convenient. However, as a project, Django wasn't willing to allow *any* possibility of an exploit, now or in the future, so we had to remove the exception.
 
Also, was this ever really fixed in Django?  Rails stores the token in the session, but Django stores the token in a cookie.  But since the vulnerability allowed setting arbitrary headers, couldn't an attacker just set the Cookie header to set the token to be whatever they wanted, and submit a token in the form that matched?  I ask because Play has an option that allows storing the token in a cookie, and I'd like to fully understand what if any issues there are with that (I can see from the Django source code that mitm attacks with SSL are a big pain to deal with for one).

I'll stand corrected on this, but the vulnerability wasn't about *completely* arbitrary headers -- it was just the extension headers. To the best of my knowledge, cookies are still safe -- they can't be set across domains, unless you have either a MITM attack vector, or a subdomain/wildcard cookie.

Yours,
Russ Magee %-)

James Roper

unread,
Aug 19, 2013, 8:11:55 AM8/19/13
to django-d...@googlegroups.com
Thanks very much for your reply, knowing the reasoning behind the decisions made really helps.

Cheers,

James


--
You received this message because you are subscribed to a topic in the Google Groups "Django developers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/75hNjzboNkM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.

Reply all
Reply to author
Forward
0 new messages