diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-08-19 12:06:00 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-08-19 12:06:55 +0200 |
| commit | 7eaa2776e1f176863c00b961bc76b28a3b5293c7 (patch) | |
| tree | e290620e5d25c633d9ef736feb2ccda75c799cf7 | |
| parent | b2fc5292b23cd6689063c3ff97eaa802400d8b8a (diff) | |
[3.1.x] Fixed #31895 -- Fixed crash when decoding invalid session data.
Thanks Matt Hegarty for the report.
Regression in d4fff711d4c97356bd6ba1273d2a5e349326eb5f.
Backport of 4376c2c7f8cd9c7604a7d053b3c4022dd5ac2795 from master
| -rw-r--r-- | django/contrib/sessions/backends/base.py | 9 | ||||
| -rw-r--r-- | docs/releases/3.1.1.txt | 3 | ||||
| -rw-r--r-- | tests/sessions_tests/tests.py | 15 |
3 files changed, 22 insertions, 5 deletions
diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py index 187e14b1b7..0f06b23e93 100644 --- a/django/contrib/sessions/backends/base.py +++ b/django/contrib/sessions/backends/base.py @@ -121,6 +121,15 @@ class SessionBase: return signing.loads(session_data, salt=self.key_salt, serializer=self.serializer) # RemovedInDjango40Warning: when the deprecation ends, handle here # exceptions similar to what _legacy_decode() does now. + except signing.BadSignature: + try: + # Return an empty session if data is not in the pre-Django 3.1 + # format. + return self._legacy_decode(session_data) + except Exception: + logger = logging.getLogger('django.security.SuspiciousSession') + logger.warning('Session data corrupted') + return {} except Exception: return self._legacy_decode(session_data) diff --git a/docs/releases/3.1.1.txt b/docs/releases/3.1.1.txt index f0369d017a..d2c08fed5a 100644 --- a/docs/releases/3.1.1.txt +++ b/docs/releases/3.1.1.txt @@ -32,3 +32,6 @@ Bugfixes * Fixed a data loss possibility, following a regression in Django 2.0, when copying model instances with a cached fields value (:ticket:`31863`). + +* Fixed a regression in Django 3.1 that caused a crash when decoding an invalid + session data (:ticket:`31895`). diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py index e7615d0f11..29b58073e1 100644 --- a/tests/sessions_tests/tests.py +++ b/tests/sessions_tests/tests.py @@ -333,11 +333,16 @@ class SessionTestsMixin: self.assertEqual(self.session._legacy_decode(encoded), data) def test_decode_failure_logged_to_security(self): - bad_encode = base64.b64encode(b'flaskdj:alkdjf').decode('ascii') - with self.assertLogs('django.security.SuspiciousSession', 'WARNING') as cm: - self.assertEqual({}, self.session.decode(bad_encode)) - # The failed decode is logged. - self.assertIn('corrupted', cm.output[0]) + tests = [ + base64.b64encode(b'flaskdj:alkdjf').decode('ascii'), + 'bad:encoded:value', + ] + for encoded in tests: + with self.subTest(encoded=encoded): + with self.assertLogs('django.security.SuspiciousSession', 'WARNING') as cm: + self.assertEqual(self.session.decode(encoded), {}) + # The failed decode is logged. + self.assertIn('Session data corrupted', cm.output[0]) def test_actual_expiry(self): # this doesn't work with JSONSerializer (serializing timedelta) |
