James Bennett wrote:
> On Fri, May 15, 2009 at 1:55 PM, Tim Chase
> <[email protected]> wrote:
>> One more option that occurs to me is that you can stash all of
>> the POSTed variables into a session-store with a hash key,
>> redirect with some sort of "load POST variables from this
>> hash-key" GET page, and then when the login is done, redirect to
>> your form, loading the contents from the session-store based on
>> the key you pass in.
> 
> The Django admin used to do this, actually.
> 
> Then we stopped doing it because it turns out to be a gigantic
> security hole that can't be closed -- doing this basically consists of
> building a free CSRF exploit into your site.

I've read up at [1] and it seems that for a one-time transfer, if 
the token was a hash (effectively unguessable), and a successful 
transfer deleted the item from the session-store when complete, 
it removes the problem.  Sample session:

   a) unauthenticated user requests form/view X
   b) user fills out form
   c) user tries to save/POST, but view X requires a logged-
      in user
   d) view X saves the posted data to a session table
   e) view X builds a signed token/hash with that session ID
      such as sha1("%s%s" % (settings.SECRET_KEY, inserted_id))
   f) view X redirects to login page with a redirect back to X
      including the token in the GET parameters
   g) user arrives at login page with uname/pwd boxes and token
      as a hidden field value
   h) user posts to login page, signing in
   j) login page redirects user to view X, passing the "load
      data from this saved slot" hash
   k) user hits view X which notices the "load data from this
      saved slot" GET parameter and that the user is now
      authenticated, so it loads the data into the form
   m) view X then deletes the data from the session-store[2]
   n) user is now at view/page X with their original data, but
      is now signed in
   p) user can now save/POST a 2nd time, this time as an
      authenticated user

My understanding from [1] is that a successful CSRF requires a 
logged in user to perform the action (which doesn't occur until 
"h"), and then being able to build a known GET url (which 
requires the generated SHA1 token) so the window of opportunity 
for exploit is one redirect worth of time (h-m), and finally 
being able to make the POST directly.  The only potential hole I 
see is that an existing authenticated user might theoretically be 
able to guess the token and load somebody else's data to post as 
themselves, but this would require guessing the SHA1 token. 
Additional user-associated information could be required by the 
view to mitigate this, but if attackers knowing your 
SHA1/SECRET_KEY is a concern, you have other problems ;-)

I'm missing where the window of CSRF opportunity lurks.  Or maybe 
I made assumptions about the flow that protect against less safe 
workflows.  Or perhaps I poorly explained what I envisioned.  Am 
I still off-base with this idea, vulnerable to CSRF?

-tim

[1]
http://en.wikipedia.org/wiki/Csrf

[2]
at this point, I'd delete that token as well as purge out any 
other tokens older than $TIMEDELTA to keep the session-store from 
growing humongous with unused session data.








--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" 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-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to