summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-08-19 12:06:00 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-08-19 12:06:55 +0200
commit7eaa2776e1f176863c00b961bc76b28a3b5293c7 (patch)
treee290620e5d25c633d9ef736feb2ccda75c799cf7
parentb2fc5292b23cd6689063c3ff97eaa802400d8b8a (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.py9
-rw-r--r--docs/releases/3.1.1.txt3
-rw-r--r--tests/sessions_tests/tests.py15
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)