Ticket #18194: files-sessions-server-expiry-3.patch

File files-sessions-server-expiry-3.patch, 3.5 KB (added by crodjer, 3 years ago)

Patch 3 - Use the signing frework to handle session expiry and integrity

  • django/contrib/sessions/backends/base.py

    diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py
    index 5a637e2..20d1279 100644
    a b from django.utils.crypto import constant_time_compare 
    1212from django.utils.crypto import get_random_string
    1313from django.utils.crypto import salted_hmac
    1414from django.utils import timezone
     15from django.core import signing
    1516
    1617class CreateError(Exception):
    1718    """
    class SessionBase(object): 
    3132        self._session_key = session_key
    3233        self.accessed = False
    3334        self.modified = False
     35        self.signer = signing.TimestampSigner()
    3436
    3537    def __contains__(self, key):
    3638        return key in self._session
    class SessionBase(object): 
    7678
    7779    def encode(self, session_dict):
    7880        "Returns the given session dictionary pickled and encoded as a string."
    79         pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
    80         hash = self._hash(pickled)
    81         return base64.encodestring(hash + ":" + pickled)
     81        serialized = pickle.dumps(session_dict)
     82        return self.signer.sign(serialized)
    8283
    8384    def decode(self, session_data):
    84         encoded_data = base64.decodestring(session_data)
    8585        try:
    86             # could produce ValueError if there is no ':'
    87             hash, pickled = encoded_data.split(':', 1)
    88             expected_hash = self._hash(pickled)
    89             if not constant_time_compare(hash, expected_hash):
    90                 raise SuspiciousOperation("Session data corrupted")
    91             else:
    92                 return pickle.loads(pickled)
     86            serialized = str(self.signer.unsign(session_data,
     87                                                settings.SESSION_COOKIE_AGE))
     88            return pickle.loads(serialized)
     89
     90        except signing.BadSignature:
     91            self.create()
     92
     93        # Signing framework handles any possiblity of ValueError and
     94        # SuspiciousOperation. So, this exception block will handle unpickling
     95        # exceptions only.
    9396        except Exception:
    9497            # ValueError, SuspiciousOperation, unpickling exceptions. If any of
    9598            # these happen, just return an empty dictionary (an empty session).
  • django/contrib/sessions/tests.py

    diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
    index 92ea6bb..c23a137 100644
    a b class FileSessionTests(SessionTestsMixin, unittest.TestCase): 
    345345        self.assertRaises(SuspiciousOperation,
    346346                          self.backend("a/b/c").load)
    347347
     348    # This test fails with cookie (which is fine I suppose) and cache backends,
     349    # thats why added it to file tests only.
     350    @override_settings(SESSION_COOKIE_AGE=0)
     351    def test_onload_expiry_check(self):
     352        """
     353        Test to ensure that expiry of session is checked on-load
     354        """
     355
     356        self.session['test-data'] = True
     357        old_key = self.session.session_key
     358        self.session.save()
     359        self.assertTrue(self.session.get('test-data'))
     360        self.session.load()
     361        new_key = self.session.session_key
     362
     363        # Make sure a new key was generated after the invalidation of the old
     364        # one.
     365        self.assertNotEqual(old_key, new_key)
     366        # The key test-data should not be present in the session.
     367        self.assertFalse(self.session.get('test-data'))
    348368
    349369class CacheSessionTests(SessionTestsMixin, unittest.TestCase):
    350370
Back to Top