On 28/07/13 00:12, Shai Berger wrote: > Hi everybody, > > TL;DR: A simple change can make Django's CSRF protection a little better; an > additional, slightly less simple one, can also make it look better. > > Django's CSRF protection scheme is a bit unusual; unlike most such schemes, > it > does not rely on a value stored in the server that needs to be matched by a > submitted token and is replaced with every submission, but rather on a > constant value stored in a cookie. This generally works (for details of how > and under what conditions exactly, see [1]), but has two minor problems: > > 1) It is unusual, and in particular diverges from what OWASP[2] > recommends[3]; > as a result, security analysts often think it is not secure. They have been > proven wrong in all cases members of core are aware of, but proving it again > and again is a nuisance, and there may be bad PR related to this.
I understand your point, but personally I'm not that impressed by everything that OWASP does. In general they are good, but some of their previous recommendations have been way off. In one case, concerning CSRF tokens in GET parameters, I had a long email exchange with them. They did eventually (kind of) concede my point, but they didn't bother to fix anything. Instead they asked me to do it, but it took me about 2 years to actually get a login for their wiki to be able to do that. > > To improve on both problem issues, while keeping the advantages, I suggest > the > following modifications: > > a) Use a signed cookie for csrftoken -- using Django's existing signing > facility[4], this means signing the cookie with the SECRET_KEY from the > settings; so that an attacker cannot set arbitrary cookies, and changing the > SECRET_KEY after a compromise immeiately invalidates csrftoken cookies. I don't understand how this is supposed to work. For most Django sites, it is trivial to get a page from a site and extract a CSRF token and/or CSRF cookie value. (The same-origin policy means that you can't do it client-side from a different website, but a tiny server-side script can do it). An attacker can use this to forge a token or cookie that looks like it was signed by the Django site, because it was. If SECRET_KEY is changed, the attacker can just get a new signed value. The only way this would work is if there is a user specific element that stops the attacker from getting a CSRF token that will work on the victim. To do this, you have to go back to tying CSRF tokens to the session, or something equivalent. It's for this reason that I'm pretty unenthusiastic about the proposed changes. I think adding complexity is more likely to confuse us. Luke -- "Because Your lovingkindness is better than life, My lips shall praise You." (Ps 63:3) Luke Plant || http://lukeplant.me.uk/ -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/django-developers. For more options, visit https://groups.google.com/groups/opt_out.
