Good morning, I have also looked into this mechanism and I wanted to add to the discussion. Many of my thoughts regard not simply Django's "stock" behavior, but the ease with which a developer may unexpectedly expose their work to security vulnerabilities.
One important note to remember is that an application _can_ inject a CSRF cookie above the domain via settings.CSRF_COOKIE_DOMAIN, settings.CSRF_COOKIE_PATH and settings.CSRF_COOKIE_SECURE. This places a great onus of responsibility on the developer to ensure that this cookie is never leaked or set above an appropriate domain. An example where this is dangerous would be a site with multiple subdomains using the same django instance and multiple applications to serve the same site. Because the cookie is available to client side applications as well as server side applications which are potentially outside the developer's control, a potential to exploit or leak the CSRF is present if the aforementioned settings are not secure. A new token isn't generated for each request because in the case of an application exception, it's important to not leave the user stranded. This could be worked around by storing a set of valid CSRF tokens at the database level and expiring them as needed. Potentially, this would be a good way to expire CSRF tokens prior to the cookie expiration as well - while at the same time ensuring the session hasn't been hijacked. Such a middleware seems to be what Dr. Winterbottom is looking for to resolve his security concerns. The implementation would be rather straightforward as well. Is there value right now in developing something like this for the community at large? peace, Ryan McIntosh Software Architect PeaceWorks Technology Solutions ph: (204) 480-0314 cell: (204) 770-3682 [email protected] ----- Original Message ----- From: "David Winterbottom" <[email protected]> To: [email protected] Sent: Thursday, December 1, 2011 3:19:27 PM GMT -06:00 US/Canada Central Subject: Queries about CSRF design following penetration test All, A site I work on was penetration tested this week and several queries were raised about the site's (and hence Django's) CSRF implementation. The points seem valid to a degree but I wanted to check if there were design decisions behind the current implementation. Note, we're using Django 1.3.1. *CSRF tokens are not generated per-request or with a max age* Django's CSRF token is only generated when the cookie is not found, and as the cookie is set to a max age of a year, the token remains the same between requests (and visits). Is there a reason why a new token isn't generated for each request? I appreciate that this doesn't really open up a huge security hole, but it does differ from OWASP's recommendations: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) The security company also recommend that the CSRF token should have a maximum age so that it expires if you wait too long. *No server-side check of the CSRF token* Basically, as long as the cookie token matches the form token, the request is valid - even if they differ from what was set originally. I found some previous discussion of this ( http://groups.google.com/group/django-developers/browse_thread/thread/571e875c9c4b806f/7ece8e94d48f6586?lnk=gst&q=csrf#7ece8e94d48f6586) and it seems that setting a CSRF cookie can only be done from a site with the same top-level domain. Hence, this is only an issue if someone malicious controls a subdomain. In their examples, they are hand-crafting the HTTP request to spoof this but I guess that is not representative of what can be done via a browser-based CSRF attack. How much of a security issue is this? I'm happy to share the relevant pages of the report if anyone's interested. All thoughts appreciated. -- *Dr. David Winterbottom* Head of Programming Tangent Labs 84-86 Great Portland Street London W1W 7NR England, UK -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
