[Python-modules-commits] [python-django] 05/07: session-1.7.x.diff
Brian May
bam at moszumanska.debian.org
Sun Oct 11 02:44:55 UTC 2015
This is an automated email from the git hooks/post-receive script.
bam pushed a commit to branch debian/jessie
in repository python-django.
commit 4f049c3e12ad3ed171b5fde82406c77e39481573
Author: Carl Meyer <carl at oddbird.net>
Date: Wed Jun 10 15:45:20 2015 -0600
session-1.7.x.diff
commit ac4a54705fb9cdde832d07667843b45b208f9aad
[1.7.x] Fixed #19324 -- Avoided creating a session record when loading the session.
The session record is now only created if/when the session is modified. This
prevents a potential DoS via creation of many empty session records.
This is a security fix; disclosure to follow shortly.
Patch-Name: session-1.7.x.diff
---
django/contrib/sessions/backends/cache.py | 6 ++++--
django/contrib/sessions/backends/cached_db.py | 4 ++--
django/contrib/sessions/backends/db.py | 5 +++--
django/contrib/sessions/backends/file.py | 5 +++--
django/contrib/sessions/tests.py | 20 ++++++++++++++++++++
5 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/django/contrib/sessions/backends/cache.py b/django/contrib/sessions/backends/cache.py
index b1058b3..faeb106 100644
--- a/django/contrib/sessions/backends/cache.py
+++ b/django/contrib/sessions/backends/cache.py
@@ -27,7 +27,7 @@ class SessionStore(SessionBase):
session_data = None
if session_data is not None:
return session_data
- self.create()
+ self._session_key = None
return {}
def create(self):
@@ -49,6 +49,8 @@ class SessionStore(SessionBase):
"It is likely that the cache is unavailable.")
def save(self, must_create=False):
+ if self.session_key is None:
+ return self.create()
if must_create:
func = self._cache.add
else:
@@ -60,7 +62,7 @@ class SessionStore(SessionBase):
raise CreateError
def exists(self, session_key):
- return (KEY_PREFIX + session_key) in self._cache
+ return session_key and (KEY_PREFIX + session_key) in self._cache
def delete(self, session_key=None):
if session_key is None:
diff --git a/django/contrib/sessions/backends/cached_db.py b/django/contrib/sessions/backends/cached_db.py
index f5c14b0..5cc6f79 100644
--- a/django/contrib/sessions/backends/cached_db.py
+++ b/django/contrib/sessions/backends/cached_db.py
@@ -51,12 +51,12 @@ class SessionStore(DBStore):
logger = logging.getLogger('django.security.%s' %
e.__class__.__name__)
logger.warning(force_text(e))
- self.create()
+ self._session_key = None
data = {}
return data
def exists(self, session_key):
- if (KEY_PREFIX + session_key) in self._cache:
+ if session_key and (KEY_PREFIX + session_key) in self._cache:
return True
return super(SessionStore, self).exists(session_key)
diff --git a/django/contrib/sessions/backends/db.py b/django/contrib/sessions/backends/db.py
index a087061..3e6cdf9 100644
--- a/django/contrib/sessions/backends/db.py
+++ b/django/contrib/sessions/backends/db.py
@@ -26,7 +26,7 @@ class SessionStore(SessionBase):
logger = logging.getLogger('django.security.%s' %
e.__class__.__name__)
logger.warning(force_text(e))
- self.create()
+ self._session_key = None
return {}
def exists(self, session_key):
@@ -43,7 +43,6 @@ class SessionStore(SessionBase):
# Key wasn't unique. Try again.
continue
self.modified = True
- self._session_cache = {}
return
def save(self, must_create=False):
@@ -53,6 +52,8 @@ class SessionStore(SessionBase):
create a *new* entry (as opposed to possibly updating an existing
entry).
"""
+ if self.session_key is None:
+ return self.create()
obj = Session(
session_key=self._get_or_create_session_key(),
session_data=self.encode(self._get_session(no_load=must_create)),
diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py
index 6569daf..f886bcd 100644
--- a/django/contrib/sessions/backends/file.py
+++ b/django/contrib/sessions/backends/file.py
@@ -96,7 +96,7 @@ class SessionStore(SessionBase):
self.delete()
self.create()
except (IOError, SuspiciousOperation):
- self.create()
+ self._session_key = None
return session_data
def create(self):
@@ -107,10 +107,11 @@ class SessionStore(SessionBase):
except CreateError:
continue
self.modified = True
- self._session_cache = {}
return
def save(self, must_create=False):
+ if self.session_key is None:
+ return self.create()
# Get the session data now, before we start messing
# with the file it is stored within.
session_data = self._get_session(no_load=must_create)
diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
index 8d63aaa..6e042c7 100644
--- a/django/contrib/sessions/tests.py
+++ b/django/contrib/sessions/tests.py
@@ -171,6 +171,11 @@ class SessionTestsMixin(object):
self.assertNotEqual(self.session.session_key, prev_key)
self.assertEqual(list(self.session.items()), prev_data)
+ def test_save_doesnt_clear_data(self):
+ self.session['a'] = 'b'
+ self.session.save()
+ self.assertEqual(self.session['a'], 'b')
+
def test_invalid_key(self):
# Submitting an invalid session key (either by guessing, or if the db has
# removed the key) results in a new key being generated.
@@ -306,6 +311,21 @@ class SessionTestsMixin(object):
self.session.delete(old_session_key)
self.session.delete(new_session_key)
+ def test_session_load_does_not_create_record(self):
+ """
+ Loading an unknown session key does not create a session record.
+
+ Creating session records on load is a DOS vulnerability.
+ """
+ if self.backend is CookieSession:
+ raise unittest.SkipTest("Cookie backend doesn't have an external store to create records in.")
+ session = self.backend('someunknownkey')
+ session.load()
+
+ self.assertFalse(session.exists(session.session_key))
+ # provided unknown key was cycled, not reused
+ self.assertNotEqual(session.session_key, 'someunknownkey')
+
class DatabaseSessionTests(SessionTestsMixin, TestCase):
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django.git
More information about the Python-modules-commits
mailing list