Google Groups Home Help | Sign in
django.contrib.sessions problems
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  20 messages - Collapse all
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
mrts  
View profile
 More options Apr 3, 4:36 am
From: mrts <m...@mrts.pri.ee>
Date: Thu, 3 Apr 2008 01:36:33 -0700 (PDT)
Local: Thurs, Apr 3 2008 4:36 am
Subject: django.contrib.sessions problems
SessionStore is missing a clear() or invalidate() method that will
destroy the session. Is this intentional? If so, why? Cleaning a
session is such a common requirement for session frameworks.

Looking through tickets, I found the following relevant to general
session logic (in no particular order):
http://code.djangoproject.com/ticket/5549#comment:5
http://code.djangoproject.com/ticket/2548
http://code.djangoproject.com/ticket/3304
http://code.djangoproject.com/ticket/1180
http://code.djangoproject.com/ticket/6791
http://code.djangoproject.com/ticket/6941

Some of them are interrelated, some of them pose security risks.

Quoting #6941:
[4:17pm] jacobkm: Also, there's the question of whether the session is
tied to the browser or to the user -- we're a bit muddled there
currently.

We shouldn't be muddled on that :) .Perhaps a bit of refactoring needs
to be done on the features and logic of sessions? Beaker (http://
beaker.groovie.org), referenced in #5549, looks like a sound base to
compare Django session backend with (both feature- and logic-wise).

What I personally need is a secure session framework that
 * has a well-defined relationship to request.user, preferably being
cleanly separated from it,
 * will not be re-used under any circumstances (#6941) and is
protected against key collisions (#1180),
 * supports concurrency (uses locking throughout as Beaker does, think
mod_wsgi with threads),
 * can be cleared/destoyed,
 * supports controlling session lifetime (http://
code.djangoproject.com/ticket/2548#comment:8 describes the use case).

Regards,
Mart Sõmermaa


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mike Axiak  
View profile
 More options Apr 3, 4:48 am
From: Mike Axiak <mcax...@gmail.com>
Date: Thu, 3 Apr 2008 01:48:54 -0700 (PDT)
Local: Thurs, Apr 3 2008 4:48 am
Subject: Re: django.contrib.sessions problems
On Apr 3, 4:36 am, mrts <m...@mrts.pri.ee> wrote:

> Quoting #6941:
> [4:17pm] jacobkm: Also, there's the question of whether the session is
> tied to the browser or to the user -- we're a bit muddled there
> currently.

Let me reiterate a position that I posted on #6941. After reviewing, I
actually *don't* think we're all that muddled. A session is
{{{request.session}}} and is represented by the browser's session.
Whereas a user is {{{request.user}}} and is completely separate.

That being said, there are many use cases that would require a change
{{{request.user}}} to somehow signal the creation of a new session. I
am not sure how we should represent this this other than either making
it the forced default or having people wrap the login views.

> What I personally need is a secure session framework that
>  * has a well-defined relationship to request.user, preferably being
> cleanly separated from it,
>  * will not be re-used under any circumstances (#6941) and is
> protected against key collisions (#1180),
>  * supports concurrency (uses locking throughout as Beaker does, think
> mod_wsgi with threads),
>  * can be cleared/destoyed,
>  * supports controlling session lifetime (http://
> code.djangoproject.com/ticket/2548#comment:8 describes the use case).

After reading through these, I think most of these can be satisfied
with the proper session backend. Why not write a "secure" session
backend? (You would presumably also need to require signed cookies for
the session.) I would be interested to see what it would look like.

Cheers,
Mike Axiak


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
mrts  
View profile
 More options Apr 3, 5:23 am
From: mrts <m...@mrts.pri.ee>
Date: Thu, 3 Apr 2008 02:23:37 -0700 (PDT)
Local: Thurs, Apr 3 2008 5:23 am
Subject: Re: django.contrib.sessions problems

> After reading through these, I think most of these can be satisfied
> with the proper session backend. Why not write a "secure" session
> backend? (You would presumably also need to require signed cookies for
> the session.) I would be interested to see what it would look like.

I think a general refactoring is required. Explicit session
destruction and threading should be supported by all backends. Looks
like sessions are the only bit that may pose problems when running
Django under threaded WSGI, quoting Graham Dumpleton from
http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango:

"If any area of Django does give problems it may be its support for
sessions. This is because Django does not implement any form of global
session locking. That this is lacking though should by rights also
cause problems with multi process server configurations as well as
multithreaded servers. It may be the case though that problems may
more readily occur in a multithreaded server, especially in AJAX heavy
applications which execute many concurrent requests which require use
of sessions."

Is this correct or are there any other modules that are not thread-
safe?


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Graham Dumpleton  
View profile
 More options Apr 3, 7:35 am
From: Graham Dumpleton <Graham.Dumple...@gmail.com>
Date: Thu, 3 Apr 2008 04:35:49 -0700 (PDT)
Local: Thurs, Apr 3 2008 7:35 am
Subject: Re: django.contrib.sessions problems
On Apr 3, 8:23 pm, mrts <m...@mrts.pri.ee> wrote:

For some context of why I came out and said that, read:

  http://groups.google.com/group/django-users/browse_frm/thread/a7d4247...

What I say may not be totally correct, but the comment (which was
correcting my assumption):

"""As can be seen from
the code in django/contrib/sessions/middleware.py and models.py, we
don't do any cross-thread or cross-process locking when creating a
session instance. Maybe we well should be doing something like that
for
people who want to do simultaneous updates -- as might happen in an
AJAX
driven site -- but, right now, we do not. """

was enough for me to at least highlight it as something to watch out
for.

Graham


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Collin Grady  
View profile
 More options Apr 3, 1:24 pm
From: Collin Grady <cgr...@gmail.com>
Date: Thu, 03 Apr 2008 10:24:51 -0700
Local: Thurs, Apr 3 2008 1:24 pm
Subject: Re: django.contrib.sessions problems
Mike Axiak said the following:

> Let me reiterate a position that I posted on #6941. After reviewing, I
> actually *don't* think we're all that muddled. A session is
> {{{request.session}}} and is represented by the browser's session.
> Whereas a user is {{{request.user}}} and is completely separate.

Except request.user is loaded by using a user id stuffed in session, so they are
definitely tied together right now :)

--
Collin Grady

The reward of a thing well done is to have done it.
                -- Emerson


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
mrts  
View profile
 More options Apr 4, 8:19 am
From: mrts <m...@mrts.pri.ee>
Date: Fri, 4 Apr 2008 05:19:18 -0700 (PDT)
Local: Fri, Apr 4 2008 8:19 am
Subject: Re: django.contrib.sessions problems
I started http://code.djangoproject.com/wiki/DjangoSpecifications/Contrib/Sessions
to properly sort this out. Please edit.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jacob Kaplan-Moss  
View profile
 More options Apr 4, 9:00 am
From: "Jacob Kaplan-Moss" <jacob.kaplanm...@gmail.com>
Date: Fri, 4 Apr 2008 08:00:46 -0500
Local: Fri, Apr 4 2008 9:00 am
Subject: Re: django.contrib.sessions problems

On Fri, Apr 4, 2008 at 7:19 AM, mrts <m...@mrts.pri.ee> wrote:
>  I started http://code.djangoproject.com/wiki/DjangoSpecifications/Contrib/Sessions
>  to properly sort this out. Please edit.

No, please post here. I know you want there to be a formal spec
process, but there isn't. Right now the way we decide things is by
posting them here, and you need to do the same.

Jacob


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
mrts  
View profile
 More options Apr 4, 9:37 am
From: mrts <m...@mrts.pri.ee>
Date: Fri, 4 Apr 2008 06:37:52 -0700 (PDT)
Local: Fri, Apr 4 2008 9:37 am
Subject: Re: django.contrib.sessions problems

On Apr 4, 4:00 pm, "Jacob Kaplan-Moss" <jacob.kaplanm...@gmail.com>
wrote:

> No, please post here. I know you want there to be a formal spec
> process, but there isn't. Right now the way we decide things is by
> posting them here, and you need to do the same.

I entirely accept that. The proposal pages are complementary (and,
indeed, secondary) to discussions on the mailing list.

However, I see real value in proposal pages for non-trivial things --
once discussions reach a conclusion, they provide a reference of the
topic that is otherwise scattered around (several) tickets and mailing
list posts. Moreover, both qs-rf and nf-admin have similar
"specification" pages.

So please continue the discussion here *and* edit the page if you
like. Editing is not that important as I will do the final writeup
there in the end anyway, but I'd welcome additions.

But please, Jacob, can you provide feedback on the topic itself as
well?


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
mrts  
View profile
 More options Apr 5, 2:31 pm
From: mrts <m...@mrts.pri.ee>
Date: Sat, 5 Apr 2008 11:31:11 -0700 (PDT)
Local: Sat, Apr 5 2008 2:31 pm
Subject: Re: django.contrib.sessions problems

> Why not write a "secure" session backend? (You would presumably
> also need to require signed cookies for the session.)

The cookies are already signed. Session data +
settings.SECRET_KEY is md5-digested and tampering raises an
exception. So in that sense the sessions are already secure.
Note that it is possible to create controlled collisions for md5,
thus session data *can* actually be tampered with, so I may end
up writing a version based on sha256 HMAC instead someday.
But as of now I can live with md5-based "signing".

Once Python 2.3/4 support will be dropped, we can start using
higher-grade hash algorithms from 2.5 hashlib throughout. But
this is offtopic for current discussion and will not happen in
the foreseeable future.

The relationship between user and session
-----------------------------------------

Associating some session data to logged-in users is a common use
case. That data needs to be deleted once the user logs out.

Currently sessions and users are separated (I haven't checked how
the user is saved in the session, I assume the user is actually
stored in the session under a specific key). This is very good
and should remain so, but doesn't cater for the use-case.

I propose we add a "data bucket" to the user object that can be
used for that purpose.

>>> u = authenticate(username=username, password=password)
>>> type(u.data)
<type 'dict'>
>>> u.data['foo'] = 'bar'
>>> u.save() # pickles the data dictionary and saves it in a text

             # field
>>> u.data['foo']
'bar'
>>> logout(request)
>>> u.data

{}

It should be documented that all session data tied to a user
should be saved in that bucket. Sessions may be used for other
purposes or without django.contrib.auth, so they should
definitely remain separate from the user generally.

That would fix #6941.

I'm ready to implement this.

Clearing a session
------------------

Sessions should have a destroy() method that clears the keys and
removes the corresponding session object from the backend store.

>>> from django.contrib.sessions.backends.db import SessionStore
>>> from django.contrib.sessions.models import Session
>>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
>>> s['foo'] = 'bar'
>>> s['foo']
'bar'
>>> s.save()
>>> dbs = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> dbs.foo
'bar'
>>> s.destroy()
>>> s['foo']

Traceback (most recent call last):
  ...
KeyError: 'foo'
>>> dbs = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')

Traceback (most recent call last):
  ...
DoesNotExist: Session matching query does not exist.

After calling s.destroy(), s should be a valid session object that has
a new key.

I'm ready to implement this.

Please comment.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mike Axiak  
View profile
 More options Apr 5, 5:11 pm
From: Mike Axiak <mcax...@gmail.com>
Date: Sat, 5 Apr 2008 14:11:51 -0700 (PDT)
Local: Sat, Apr 5 2008 5:11 pm
Subject: Re: django.contrib.sessions problems
Hey mrts,
On Apr 5, 2:31 pm, mrts <m...@mrts.pri.ee> wrote:

> The cookies are already signed. Session data +
> settings.SECRET_KEY is md5-digested and tampering raises an
> exception. So in that sense the sessions are already secure.

Sorry, I didn't mean "secure" in the sense that someone can alter the
data. I meant secure in the sense that (a) there is a guarantee of no
collisions and (b) someone else cannot easily hijack the session.

I believe that Graham said was that sessions aren't "threadsafe"
because two sessions could have the same key (although it's very
unlikely). In this way, sessions aren't multi-process or multi-server
safe either. (I would venture to guess the projects that have problem
with this level of concurrency are also the projects that have
multiple servers.)

There was talk long ago of using db-level locking (either through
sequences or transactions) to ensure two sessions cannot create the
same ID. From what I can tell, this was deemed not a good fit for
Django. Since then, the session interface has changed so there is no
need to convince the Django core developers that every Django project
needs these features. You can write your own app that supports this
session key safety and a few other session-based "controversial"
features that are needed for safety. (And if the backend is good, it
might be merged into trunk as a non-default backend.)

Cheers,
Mike


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Malcolm Tredinnick  
View profile
 More options Apr 5, 11:17 pm
From: Malcolm Tredinnick <malc...@pointy-stick.com>
Date: Sun, 06 Apr 2008 13:17:31 +1000
Local: Sat, Apr 5 2008 11:17 pm
Subject: Re: django.contrib.sessions problems

On Sat, 2008-04-05 at 11:31 -0700, mrts wrote:

[...]

> Once Python 2.3/4 support will be dropped, we can start using
> higher-grade hash algorithms from 2.5 hashlib throughout. But
> this is offtopic for current discussion and will not happen in
> the foreseeable future.

It will be a while beyond that point, too, since you can't just
magically rehash everything with the new algorithms. So you have to be
able to read auth data generated with older algorithms.

> The relationship between user and session
> -----------------------------------------

> Associating some session data to logged-in users is a common use
> case. That data needs to be deleted once the user logs out.

> Currently sessions and users are separated (I haven't checked how
> the user is saved in the session, I assume the user is actually
> stored in the session under a specific key). This is very good
> and should remain so, but doesn't cater for the use-case.

> I propose we add a "data bucket" to the user object that can be
> used for that purpose.

Which would mean a user could only be logged in once each time. :-(

Session objects is the right place to store all session-related data.
It's a many-to-one relation to each user. If you want something that's
one-to-one with a user, that isn't session data and is easy to implement
via your own model, but I'm not sure it's common enough to have a common
API required in Django itself.

You'll need to elaborate more here on use-cases, I think. It might just
be that you haven't explained what you're wanting to do here.

I don't see the need for an extra method here. Why isn't this just
something logout() would do?

It's easy to destroy a session. Just call delete() on the object (that's
your destroy() method). The root issue is managing the lifetime and I'm
pretty sure that a sessions lifetime ends either when it has expired
(daily-cleanup nukes those things, or whatever equivalent you're using)
or when the user logs out -- thus explicitly ending their session. We
don't do the latter at the moment, but that would seem to be the
straightforward fix here.

Regards,
Malcolm

--
The early bird may get the worm, but the second mouse gets the cheese.
http://www.pointy-stick.com/blog/


    Reply    Reply to author    Forward