Fixed #31895 -- Fixed crash when decoding invalid session data.
Thanks Matt Hegarty for the report.
Regression in d4fff711d4
.
This commit is contained in:
parent
bf6d07730c
commit
4376c2c7f8
|
@ -121,6 +121,15 @@ class SessionBase:
|
||||||
return signing.loads(session_data, salt=self.key_salt, serializer=self.serializer)
|
return signing.loads(session_data, salt=self.key_salt, serializer=self.serializer)
|
||||||
# RemovedInDjango40Warning: when the deprecation ends, handle here
|
# RemovedInDjango40Warning: when the deprecation ends, handle here
|
||||||
# exceptions similar to what _legacy_decode() does now.
|
# 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:
|
except Exception:
|
||||||
return self._legacy_decode(session_data)
|
return self._legacy_decode(session_data)
|
||||||
|
|
||||||
|
|
|
@ -32,3 +32,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a data loss possibility, following a regression in Django 2.0, when
|
* Fixed a data loss possibility, following a regression in Django 2.0, when
|
||||||
copying model instances with a cached fields value (:ticket:`31863`).
|
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`).
|
||||||
|
|
|
@ -333,11 +333,16 @@ class SessionTestsMixin:
|
||||||
self.assertEqual(self.session._legacy_decode(encoded), data)
|
self.assertEqual(self.session._legacy_decode(encoded), data)
|
||||||
|
|
||||||
def test_decode_failure_logged_to_security(self):
|
def test_decode_failure_logged_to_security(self):
|
||||||
bad_encode = base64.b64encode(b'flaskdj:alkdjf').decode('ascii')
|
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:
|
with self.assertLogs('django.security.SuspiciousSession', 'WARNING') as cm:
|
||||||
self.assertEqual({}, self.session.decode(bad_encode))
|
self.assertEqual(self.session.decode(encoded), {})
|
||||||
# The failed decode is logged.
|
# The failed decode is logged.
|
||||||
self.assertIn('corrupted', cm.output[0])
|
self.assertIn('Session data corrupted', cm.output[0])
|
||||||
|
|
||||||
def test_actual_expiry(self):
|
def test_actual_expiry(self):
|
||||||
# this doesn't work with JSONSerializer (serializing timedelta)
|
# this doesn't work with JSONSerializer (serializing timedelta)
|
||||||
|
|
Loading…
Reference in New Issue