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
-~----------~----~----~----~------~----~------~--~---