Fixed a subtle corner case whereby sending a bad session ID generates new (unused) session entries in the database table.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@7001 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-01-06 12:53:09 +00:00
parent 70fe1ef262
commit 041e24dbde
2 changed files with 20 additions and 16 deletions

View File

@ -10,40 +10,42 @@ class SessionStore(SessionBase):
""" """
def __init__(self, session_key=None): def __init__(self, session_key=None):
super(SessionStore, self).__init__(session_key) super(SessionStore, self).__init__(session_key)
def load(self): def load(self):
try: try:
s = Session.objects.get( s = Session.objects.get(
session_key = self.session_key, session_key = self.session_key,
expire_date__gt=datetime.datetime.now() expire_date__gt=datetime.datetime.now()
) )
return self.decode(s.session_data) return self.decode(s.session_data)
except (Session.DoesNotExist, SuspiciousOperation): except (Session.DoesNotExist, SuspiciousOperation):
# Create a new session_key for extra security. # Create a new session_key for extra security.
self.session_key = self._get_new_session_key() self.session_key = self._get_new_session_key()
self._session_cache = {} self._session_cache = {}
# Save immediately to minimize collision # Save immediately to minimize collision
self.save() self.save()
# Ensure the user is notified via a new cookie.
self.modified = True
return {} return {}
def exists(self, session_key): def exists(self, session_key):
try: try:
Session.objects.get(session_key=session_key) Session.objects.get(session_key=session_key)
except Session.DoesNotExist: except Session.DoesNotExist:
return False return False
return True return True
def save(self): def save(self):
Session.objects.create( Session.objects.create(
session_key = self.session_key, session_key = self.session_key,
session_data = self.encode(self._session), session_data = self.encode(self._session),
expire_date = datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE) expire_date = datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE)
) )
def delete(self, session_key): def delete(self, session_key):
try: try:
Session.objects.get(session_key=session_key).delete() Session.objects.get(session_key=session_key).delete()
except Session.DoesNotExist: except Session.DoesNotExist:
pass pass

View File

@ -10,31 +10,31 @@ class SessionStore(SessionBase):
""" """
def __init__(self, session_key=None): def __init__(self, session_key=None):
self.storage_path = getattr(settings, "SESSION_FILE_PATH", tempfile.gettempdir()) self.storage_path = getattr(settings, "SESSION_FILE_PATH", tempfile.gettempdir())
# Make sure the storage path is valid. # Make sure the storage path is valid.
if not os.path.isdir(self.storage_path): if not os.path.isdir(self.storage_path):
raise ImproperlyConfigured("The session storage path %r doesn't exist. "\ raise ImproperlyConfigured("The session storage path %r doesn't exist. "\
"Please set your SESSION_FILE_PATH setting "\ "Please set your SESSION_FILE_PATH setting "\
"to an existing directory in which Django "\ "to an existing directory in which Django "\
"can store session data." % self.storage_path) "can store session data." % self.storage_path)
self.file_prefix = settings.SESSION_COOKIE_NAME self.file_prefix = settings.SESSION_COOKIE_NAME
super(SessionStore, self).__init__(session_key) super(SessionStore, self).__init__(session_key)
def _key_to_file(self, session_key=None): def _key_to_file(self, session_key=None):
""" """
Get the file associated with this session key. Get the file associated with this session key.
""" """
if session_key is None: if session_key is None:
session_key = self.session_key session_key = self.session_key
# Make sure we're not vulnerable to directory traversal. Session keys # Make sure we're not vulnerable to directory traversal. Session keys
# should always be md5s, so they should never contain directory components. # should always be md5s, so they should never contain directory components.
if os.path.sep in session_key: if os.path.sep in session_key:
raise SuspiciousOperation("Invalid characters (directory components) in session key") raise SuspiciousOperation("Invalid characters (directory components) in session key")
return os.path.join(self.storage_path, self.file_prefix + session_key) return os.path.join(self.storage_path, self.file_prefix + session_key)
def load(self): def load(self):
session_data = {} session_data = {}
try: try:
@ -46,6 +46,8 @@ class SessionStore(SessionBase):
self._session_key = self._get_new_session_key() self._session_key = self._get_new_session_key()
self._session_cache = {} self._session_cache = {}
self.save() self.save()
# Ensure the user is notified via a new cookie.
self.modified = True
finally: finally:
session_file.close() session_file.close()
except(IOError): except(IOError):
@ -66,12 +68,12 @@ class SessionStore(SessionBase):
if os.path.exists(self._key_to_file(session_key)): if os.path.exists(self._key_to_file(session_key)):
return True return True
return False return False
def delete(self, session_key): def delete(self, session_key):
try: try:
os.unlink(self._key_to_file(session_key)) os.unlink(self._key_to_file(session_key))
except OSError: except OSError:
pass pass
def clean(self): def clean(self):
pass pass