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:
parent
70fe1ef262
commit
041e24dbde
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue