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.


Reply via email to