On Mon, 2010-09-06 at 22:39 +0200, Patryk Zawadzki wrote:

> Another approach would be not to use a cookie at all. For each {%
> csrf_token %} use a slightly modified variant of the above
> encode_cookie function with:
> 
> values = {
>     'host: request.META['HTTP_HOST'],
>     'scheme': request.is_secure(),
>     'user_ip': request.META['REMOTE_ADDR'],
>     'user_agent': request.META['HTTP_USER_AGENT'],
>     'ttl': time.time() + 30*60,
> }
> 
> Then when handling a POST request, decipher the token and compare each
> META field with the ones from the request and validate ttl against
> time.time(). I believe it's not less secure than the current
> implementation and solves two problems:
>
> 1) each form served gets its own ttl, an attacker can't keep pinging
> the server to keep the token alive
> 2) each token serves for a single use and will inevitably timeout in
> 30 minutes while still allowing you to open two forms in two browser
> tabs and submit each of them separately

Your method is quite flawed:

1) Use of IP address - a bad idea for the reasons I mentioned in my
other message.

2) The use of user agent does nothing to stop an attacker, even for an
attacker who isn't a MitM:

Consider an attacker who lures you to his site e.g.:
http://evil.com/somepage.php

somepage.php can read your user agent, and make a request to
http://target.com/some-page-with-form/ with the same user agent to get a
valid CSRF token.  (If he is behind the same firewall as you, he will
automatically have the same public IP, so adding the IP address is not a
perfect cure for this, even if we could do it, which we can't).

somepage.php then returns a page which has a form which targets
http://target.com/some-page-with-form/ and includes the CSRF token. The
token is valid and unused, and the attacker can proceed.

I don't think that adding a timeout will really ever help with CSRF.
The nature of CSRF attacks means that the attacker is massively more
likely to be able to attack 'now' (which is within a few seconds, the
time for a few HTTP requests to complete) rather than 'later', so
timeouts just don't help. In addition, they add nuisance for the user -
it's quite possible for someone to leave their machine for 30 minutes
and come back to it and want to carry on what they were doing.

Luke

-- 
 A mosquito cried out in pain:
 "A chemist has poisoned my brain!"
 The cause of his sorrow
 was para-dichloro-
 diphenyltrichloroethane

Luke Plant || http://lukeplant.me.uk/

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to