Storing objects as session variables

125 views
Skip to first unread message

nki...@gmail.com

unread,
Apr 16, 2006, 1:57:44 PM4/16/06
to web.py
Hi, can anyone tell me what a good way of storing session variables is
using a web.py framework? I'd like to store variables that are more
than just flat text: for example, lists or dictionaries. I saw that
flup has some built-in middleware for it but wasn't sure if it
supported such objects or if there is a better way. Basically I'm
trying to create a web framework for running scientific experiments,
for which there may be significant information associated with each
user which would be annoying to store as flat text. Thanks!

Aaron Swartz

unread,
Apr 16, 2006, 2:14:34 PM4/16/06
to we...@googlegroups.com

If you're OK with only storing the variables for the duration of the
session (i.e. not persisting across server restarts), then an easy way
is to store the data in some sort of dictionary and save the key into
the dictionary as a cookie.

nki...@gmail.com

unread,
Apr 16, 2006, 8:06:13 PM4/16/06
to web.py
No problem with limiting it to server restarts in general, but I'm
running web.py as CGI, and thus I believe the dictionary would be wiped
each time (please correct me if I'm wrong)...

Aaron Swartz

unread,
Apr 17, 2006, 7:36:01 AM4/17/06
to we...@googlegroups.com
> No problem with limiting it to server restarts in general, but I'm
> running web.py as CGI, and thus I believe the dictionary would be wiped
> each time (please correct me if I'm wrong)...

Yeah, that's correct.

Another way is to store the whole thing in the cookie by pickling it.
I don't know how big your data is but I assume there are size limits
on cookies, so this wouldn't really work for very complicated things.

You could even do it compressed:

def usersave(obj): return web.setcookie('state',
zlib.compress(pickle.dumps(obj)))
def userget(obj): return
pickle.loads(zlib.decompress(web.cookies().get('state', '')))

Otherwise you'll have to use some persistant storage mechanism like a
file on disk or a database or something.

Jon Rosebaugh

unread,
Apr 17, 2006, 11:18:40 AM4/17/06
to we...@googlegroups.com
On 4/17/06, Aaron Swartz <m...@aaronsw.com> wrote:
> Another way is to store the whole thing in the cookie by pickling it.
> I don't know how big your data is but I assume there are size limits
> on cookies, so this wouldn't really work for very complicated things.

Please, _please_, do not do this. This is like SQL injection, except
instead of giving the attacker access to your database, you're giving
him access to the python interpreter instead.

I quote from the pickle documentation: The pickle module is not
intended to be secure against erroneous or maliciously constructed
data. Never unpickle data received from an untrusted or
unauthenticated source.

If you must do this, I'd recommend using JSON. It'll compress well,
and it'll be easier to do a basic sanity check on it. Also, it'll be
less likely to allow an attacker to include bad stuff.

David Terrell

unread,
Apr 17, 2006, 11:44:14 AM4/17/06
to we...@googlegroups.com

If you're running webpy as cgi, I presume you're using flup?

http://webpy.org/track/wiki/SessionsWithFlup

If you have a lot of classes you could probably have a base class
that does self.session = web.ctx.environ[...].session in __init__
and use self.session in your GET/POST handlers.

Untested. Caveat Emptor.

--
David Terrell
d...@meat.net
((meatspace)) http://meat.net/

Aaron Swartz

unread,
Apr 17, 2006, 5:30:51 PM4/17/06
to we...@googlegroups.com
>> Another way is to store the whole thing in the cookie by pickling it.
>
> Please, _please_, do not do this. This is like SQL injection, except
> instead of giving the attacker access to your database, you're giving
> him access to the python interpreter instead.
>
> I quote from the pickle documentation: The pickle module is not
> intended to be secure against erroneous or maliciously constructed
> data. Never unpickle data received from an untrusted or
> unauthenticated source.

Oops, yeah. Don't use the pickle module. Someone should add JSON to
the standard library.

David Terrell

unread,
Apr 17, 2006, 6:32:00 PM4/17/06
to we...@googlegroups.com

If you absolutely positively HAVE to store real state objects on the
clientside, they'd better be encrypted with an HMAC, because you never
know what's going to be an attack vector to subvert your library.

For a brief(!) example of how to do this, try this on:

http://meat.net/src/securecookie.py
requires pycrypto: http://www.amk.ca/python/code/crypto

Jon Rosebaugh

unread,
Apr 17, 2006, 9:00:30 PM4/17/06
to we...@googlegroups.com
On 4/17/06, Aaron Swartz <m...@aaronsw.com> wrote:
> Oops, yeah. Don't use the pickle module. Someone should add JSON to
> the standard library.

Well, easy_install simplejson isn't _that_ hard.

Jonas Galvez

unread,
Apr 17, 2006, 11:16:34 PM4/17/06
to we...@googlegroups.com
Jon Rosebaugh wrote:
> Well, easy_install simplejson isn't _that_ hard.

simplejson is very well written, but there's a catch. If you're doing
UTF-8, make sure you ensure_ascii=False whenever calling dumps(). I
don't know what it is with it that it will give you funky \uSOMETHING
sequences for every non-ascii byte, and although that may display
right in HTML/JS, you should want to keep raw UTF-8 for better
interoperability (specially with other JSON parsers).

--Jonas Galvez

nki...@gmail.com

unread,
Apr 18, 2006, 12:39:56 AM4/18/06
to web.py
Thanks to everyone for the very helpful comments -- good to know to
avoid the pickling/unpickling of client side data if not necessary.
Does anyone know whether the flup session handling supports storing
lists/dictionaries or just flat text (though I suppose I could pickle
and store as a string if needed)?

Reply all
Reply to author
Forward
0 new messages