Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find user id from session_data from django_session table?

In django_session table session_data is stored which is first pickled using pickle module of Python and then encoded in base64 by using base64 module of Python.

I got the decoded pickled session_data.

session_data from django_session table:

gAJ9cQEoVQ9fc2Vzc2lvbl9leHBpcnlxAksAVRJfYXV0aF91c2VyX2JhY2tlbmRxA1UpZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmRxBFUNX2F1dGhfdXNlcl9pZHEFigECdS5iZmUwOWExOWI0YTZkN2M0NDc2MWVjZjQ5ZDU0YjNhZA== 

after decoding it by base64.decode(session_data):

 \x80\x02}q\x01(U\x0f_session_expiryq\x02K\x00U\x12_auth_user_backendq\x03U)django.contrib.auth.backends.ModelBackendq\x04U\r_auth_user_idq\x05\x8a\x01\x02u.bfe09a19b4a6d7c44761ecf49d54b3ad 

I want to find out the value of auth_user_id from auth_user_idq\x05\x8a\x01\x02u.

like image 762
Ketan Yekale Avatar asked Nov 04 '10 12:11

Ketan Yekale


People also ask

Can you outline and briefly explain what session frameworks do?

The session framework lets you implement this sort of behavior, allowing you to store and retrieve arbitrary data on a per-site-visitor basis.

What is session and cookies in Django?

Django provides a session framework that lets you store and retrieve data on a per-site-visitor basis. Django abstracts the process of sending and receiving cookies, by placing a session ID cookie on the client side, and storing all the related data on the server side. So the data itself is not stored client side.


2 Answers

I had trouble with Paulo's method (see my comment on his answer), so I ended up using this method from a scottbarnham.com blog post:

from django.contrib.sessions.models import Session from django.contrib.auth.models import User  session_key = '8cae76c505f15432b48c8292a7dd0e54'  session = Session.objects.get(session_key=session_key) uid = session.get_decoded().get('_auth_user_id') user = User.objects.get(pk=uid)  print user.username, user.get_full_name(), user.email 
like image 57
Dolan Antenucci Avatar answered Oct 15 '22 01:10

Dolan Antenucci


NOTE: format changed since original answer, for 1.4 and above see the update below

import pickle  data = pickle.loads(base64.decode(session_data))  >>> print data {'_auth_user_id': 2L, '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend',  '_session_expiry': 0} 

[update]

My base64.decode requires filename arguments, so then I tried base64.b64decode, but this returned "IndexError: list assignment index out of range".

I really don't know why I used the base64 module, I guess because the question featured it.

You can just use the str.decode method:

>>> pickle.loads(session_data.decode('base64')) {'_auth_user_id': 2L, '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend',  '_session_expiry': 0} 

I found a work-around (see answer below), but I am curious why this doesn't work.

Loading pickled data from user sources (cookies) is a security risk, so the session_data format was changed since this question was answered (I should go after the specific issue in Django's bug tracker and link it here, but my pomodoro break is gone).

The format now (since Django 1.4) is "hash:json-object" where the first 40 byte hash is a crypto-signature and the rest is a JSON payload. For now you can ignore the hash (it allows checking if the data was not tampered by some cookie hacker).

>>> json.loads(session_data.decode('base64')[41:]) {u'_auth_user_backend': u'django.contrib.auth.backends.ModelBackend',  u'_auth_user_id': 1} 
like image 39
Paulo Scardine Avatar answered Oct 15 '22 00:10

Paulo Scardine