VYPR
High severityNVD Advisory· Published Jul 14, 2015· Updated May 6, 2026

CVE-2015-5143

CVE-2015-5143

Description

The session backends in Django before 1.4.21, 1.5.x through 1.6.x, 1.7.x before 1.7.9, and 1.8.x before 1.8.3 allows remote attackers to cause a denial of service (session store consumption) via multiple requests with unique session keys.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
DjangoPyPI
< 1.4.211.4.21
DjangoPyPI
>= 1.5, < 1.7.91.7.9
DjangoPyPI
>= 1.8, < 1.8.31.8.3

Affected products

57
  • cpe:2.3:a:djangoproject:django:1.6:-:*:*:*:*:*:*+ 49 more
    • cpe:2.3:a:djangoproject:django:1.6:-:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta3:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta4:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.6:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.7:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.8:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.9:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.10:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.20:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:alpha:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:beta:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.6:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.7:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.8:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.9:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.10:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.11:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.12:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta3:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta4:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:rc1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:rc2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:rc3:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.6:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.7:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.8:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7.9:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.8.0:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.8.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.8.2:*:*:*:*:*:*:*
  • cpe:2.3:o:debian:debian_linux:7.0:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:o:debian:debian_linux:7.0:*:*:*:*:*:*:*
    • cpe:2.3:o:debian:debian_linux:8.0:*:*:*:*:*:*:*
  • cpe:2.3:o:oracle:solaris:11.3:*:*:*:*:*:*:*
  • cpe:2.3:o:canonical:ubuntu_linux:12.04:*:*:*:lts:*:*:*+ 3 more
    • cpe:2.3:o:canonical:ubuntu_linux:12.04:*:*:*:lts:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:14.04:*:*:*:lts:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:15.04:*:*:*:*:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:15.10:*:*:*:*:*:*:*

Patches

3
1828f4341ec5

[1.7.x] Fixed #19324 -- Avoided creating a session record when loading the session.

https://github.com/django/djangoCarl MeyerJun 10, 2015via ghsa
7 files changed · +74 8
  • django/contrib/sessions/backends/cached_db.py+2 2 modified
    @@ -51,12 +51,12 @@ def load(self):
                         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)
     
    
  • django/contrib/sessions/backends/cache.py+4 2 modified
    @@ -27,7 +27,7 @@ def load(self):
                 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 @@ def create(self):
                 "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 @@ def save(self, must_create=False):
                 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:
    
  • django/contrib/sessions/backends/db.py+3 2 modified
    @@ -26,7 +26,7 @@ def load(self):
                     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 @@ def create(self):
                     # Key wasn't unique. Try again.
                     continue
                 self.modified = True
    -            self._session_cache = {}
                 return
     
         def save(self, must_create=False):
    @@ -53,6 +52,8 @@ def save(self, must_create=False):
             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)),
    
  • django/contrib/sessions/backends/file.py+3 2 modified
    @@ -96,7 +96,7 @@ def load(self):
                         self.delete()
                         self.create()
             except (IOError, SuspiciousOperation):
    -            self.create()
    +            self._session_key = None
             return session_data
     
         def create(self):
    @@ -107,10 +107,11 @@ def create(self):
                 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)
    
  • django/contrib/sessions/tests.py+20 0 modified
    @@ -171,6 +171,11 @@ def test_cycle(self):
             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 @@ def test_actual_expiry(self):
                     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):
     
    
  • docs/releases/1.4.21.txt+21 0 modified
    @@ -5,3 +5,24 @@ Django 1.4.21 release notes
     *July 8, 2015*
     
     Django 1.4.21 fixes several security issues in 1.4.20.
    +
    +Denial-of-service possibility by filling session store
    +======================================================
    +
    +In previous versions of Django, the session backends created a new empty record
    +in the session storage anytime ``request.session`` was accessed and there was a
    +session key provided in the request cookies that didn't already have a session
    +record. This could allow an attacker to easily create many new session records
    +simply by sending repeated requests with unknown session keys, potentially
    +filling up the session store or causing other users' session records to be
    +evicted.
    +
    +The built-in session backends now create a session record only if the session
    +is actually modified; empty session records are not created. Thus this
    +potential DoS is now only possible if the site chooses to expose a
    +session-modifying view to anonymous users.
    +
    +As each built-in session backend was fixed separately (rather than a fix in the
    +core sessions framework), maintainers of third-party session backends should
    +check whether the same vulnerability is present in their backend and correct
    +it if so.
    
  • docs/releases/1.7.9.txt+21 0 modified
    @@ -6,6 +6,27 @@ Django 1.7.9 release notes
     
     Django 1.7.9 fixes several security issues and bugs in 1.7.8.
     
    +Denial-of-service possibility by filling session store
    +======================================================
    +
    +In previous versions of Django, the session backends created a new empty record
    +in the session storage anytime ``request.session`` was accessed and there was a
    +session key provided in the request cookies that didn't already have a session
    +record. This could allow an attacker to easily create many new session records
    +simply by sending repeated requests with unknown session keys, potentially
    +filling up the session store or causing other users' session records to be
    +evicted.
    +
    +The built-in session backends now create a session record only if the session
    +is actually modified; empty session records are not created. Thus this
    +potential DoS is now only possible if the site chooses to expose a
    +session-modifying view to anonymous users.
    +
    +As each built-in session backend was fixed separately (rather than a fix in the
    +core sessions framework), maintainers of third-party session backends should
    +check whether the same vulnerability is present in their backend and correct
    +it if so.
    +
     Bugfixes
     ========
     
    
66d12d1ababa

[1.8.x] Fixed #19324 -- Avoided creating a session record when loading the session.

https://github.com/django/djangoCarl MeyerJun 10, 2015via ghsa
8 files changed · +95 8
  • django/contrib/sessions/backends/cached_db.py+2 2 modified
    @@ -51,12 +51,12 @@ def load(self):
                         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)
     
    
  • django/contrib/sessions/backends/cache.py+4 2 modified
    @@ -27,7 +27,7 @@ def load(self):
                 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 @@ def create(self):
                 "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 @@ def save(self, must_create=False):
                 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:
    
  • django/contrib/sessions/backends/db.py+3 2 modified
    @@ -26,7 +26,7 @@ def load(self):
                     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 @@ def create(self):
                     # Key wasn't unique. Try again.
                     continue
                 self.modified = True
    -            self._session_cache = {}
                 return
     
         def save(self, must_create=False):
    @@ -53,6 +52,8 @@ def save(self, must_create=False):
             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)),
    
  • django/contrib/sessions/backends/file.py+3 2 modified
    @@ -97,7 +97,7 @@ def load(self):
                         self.delete()
                         self.create()
             except (IOError, SuspiciousOperation):
    -            self.create()
    +            self._session_key = None
             return session_data
     
         def create(self):
    @@ -108,10 +108,11 @@ def create(self):
                 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)
    
  • docs/releases/1.4.21.txt+21 0 modified
    @@ -5,3 +5,24 @@ Django 1.4.21 release notes
     *July 8, 2015*
     
     Django 1.4.21 fixes several security issues in 1.4.20.
    +
    +Denial-of-service possibility by filling session store
    +======================================================
    +
    +In previous versions of Django, the session backends created a new empty record
    +in the session storage anytime ``request.session`` was accessed and there was a
    +session key provided in the request cookies that didn't already have a session
    +record. This could allow an attacker to easily create many new session records
    +simply by sending repeated requests with unknown session keys, potentially
    +filling up the session store or causing other users' session records to be
    +evicted.
    +
    +The built-in session backends now create a session record only if the session
    +is actually modified; empty session records are not created. Thus this
    +potential DoS is now only possible if the site chooses to expose a
    +session-modifying view to anonymous users.
    +
    +As each built-in session backend was fixed separately (rather than a fix in the
    +core sessions framework), maintainers of third-party session backends should
    +check whether the same vulnerability is present in their backend and correct
    +it if so.
    
  • docs/releases/1.7.9.txt+21 0 modified
    @@ -6,6 +6,27 @@ Django 1.7.9 release notes
     
     Django 1.7.9 fixes several security issues and bugs in 1.7.8.
     
    +Denial-of-service possibility by filling session store
    +======================================================
    +
    +In previous versions of Django, the session backends created a new empty record
    +in the session storage anytime ``request.session`` was accessed and there was a
    +session key provided in the request cookies that didn't already have a session
    +record. This could allow an attacker to easily create many new session records
    +simply by sending repeated requests with unknown session keys, potentially
    +filling up the session store or causing other users' session records to be
    +evicted.
    +
    +The built-in session backends now create a session record only if the session
    +is actually modified; empty session records are not created. Thus this
    +potential DoS is now only possible if the site chooses to expose a
    +session-modifying view to anonymous users.
    +
    +As each built-in session backend was fixed separately (rather than a fix in the
    +core sessions framework), maintainers of third-party session backends should
    +check whether the same vulnerability is present in their backend and correct
    +it if so.
    +
     Bugfixes
     ========
     
    
  • docs/releases/1.8.3.txt+21 0 modified
    @@ -11,6 +11,27 @@ Also, ``django.utils.deprecation.RemovedInDjango20Warning`` was renamed to
     1.11 (LTS), 2.0 (drops Python 2 support). For backwards compatibility,
     ``RemovedInDjango20Warning`` remains as an importable alias.
     
    +Denial-of-service possibility by filling session store
    +======================================================
    +
    +In previous versions of Django, the session backends created a new empty record
    +in the session storage anytime ``request.session`` was accessed and there was a
    +session key provided in the request cookies that didn't already have a session
    +record. This could allow an attacker to easily create many new session records
    +simply by sending repeated requests with unknown session keys, potentially
    +filling up the session store or causing other users' session records to be
    +evicted.
    +
    +The built-in session backends now create a session record only if the session
    +is actually modified; empty session records are not created. Thus this
    +potential DoS is now only possible if the site chooses to expose a
    +session-modifying view to anonymous users.
    +
    +As each built-in session backend was fixed separately (rather than a fix in the
    +core sessions framework), maintainers of third-party session backends should
    +check whether the same vulnerability is present in their backend and correct
    +it if so.
    +
     Bugfixes
     ========
     
    
  • tests/sessions_tests/tests.py+20 0 modified
    @@ -175,6 +175,11 @@ def test_cycle(self):
             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.
    @@ -313,6 +318,21 @@ def test_actual_expiry(self):
                     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):
     
    
2e47f3e401c2

[1.4.x] Fixed #19324 -- Avoided creating a session record when loading the session.

https://github.com/django/djangoCarl MeyerJun 10, 2015via ghsa
6 files changed · +54 9
  • django/contrib/sessions/backends/cached_db.py+3 2 modified
    @@ -30,11 +30,12 @@ def load(self):
                 data = None
             if data is None:
                 data = super(SessionStore, self).load()
    -            cache.set(self.cache_key, data, settings.SESSION_COOKIE_AGE)
    +            if self.session_key:
    +                cache.set(self.cache_key, data, settings.SESSION_COOKIE_AGE)
             return data
     
         def exists(self, session_key):
    -        if (KEY_PREFIX + session_key) in cache:
    +        if session_key and (KEY_PREFIX + session_key) in cache:
                 return True
             return super(SessionStore, self).exists(session_key)
     
    
  • django/contrib/sessions/backends/cache.py+4 2 modified
    @@ -25,7 +25,7 @@ def load(self):
                 session_data = None
             if session_data is not None:
                 return session_data
    -        self.create()
    +        self._session_key = None
             return {}
     
         def create(self):
    @@ -45,6 +45,8 @@ def create(self):
             raise RuntimeError("Unable to create a new session key.")
     
         def save(self, must_create=False):
    +        if self.session_key is None:
    +            return self.create()
             if must_create:
                 func = self._cache.add
             else:
    @@ -56,7 +58,7 @@ def save(self, must_create=False):
                 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:
    
  • django/contrib/sessions/backends/db.py+3 2 modified
    @@ -20,7 +20,7 @@ def load(self):
                 )
                 return self.decode(force_unicode(s.session_data))
             except (Session.DoesNotExist, SuspiciousOperation):
    -            self.create()
    +            self._session_key = None
                 return {}
     
         def exists(self, session_key):
    @@ -37,7 +37,6 @@ def create(self):
                     # Key wasn't unique. Try again.
                     continue
                 self.modified = True
    -            self._session_cache = {}
                 return
     
         def save(self, must_create=False):
    @@ -47,6 +46,8 @@ def save(self, must_create=False):
             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)),
    
  • django/contrib/sessions/backends/file.py+4 3 modified
    @@ -56,11 +56,11 @@ def load(self):
                         try:
                             session_data = self.decode(file_data)
                         except (EOFError, SuspiciousOperation):
    -                        self.create()
    +                        self._session_key = None
                 finally:
                     session_file.close()
             except IOError:
    -            self.create()
    +            self._session_key = None
             return session_data
     
         def create(self):
    @@ -71,10 +71,11 @@ def create(self):
                 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)
    
  • django/contrib/sessions/tests.py+19 0 modified
    @@ -162,6 +162,11 @@ def test_cycle(self):
             self.assertNotEqual(self.session.session_key, prev_key)
             self.assertEqual(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.
    @@ -256,6 +261,20 @@ def test_decode(self):
             encoded = self.session.encode(data)
             self.assertEqual(self.session.decode(encoded), data)
     
    +    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('deadbeef')
    +        session.load()
    +
    +        self.assertFalse(session.exists(session.session_key))
    +        # provided unknown key was cycled, not reused
    +        self.assertNotEqual(session.session_key, 'deadbeef')
     
     class DatabaseSessionTests(SessionTestsMixin, TestCase):
     
    
  • docs/releases/1.4.21.txt+21 0 modified
    @@ -5,3 +5,24 @@ Django 1.4.21 release notes
     *July 8, 2015*
     
     Django 1.4.21 fixes several security issues in 1.4.20.
    +
    +Denial-of-service possibility by filling session store
    +======================================================
    +
    +In previous versions of Django, the session backends created a new empty record
    +in the session storage anytime ``request.session`` was accessed and there was a
    +session key provided in the request cookies that didn't already have a session
    +record. This could allow an attacker to easily create many new session records
    +simply by sending repeated requests with unknown session keys, potentially
    +filling up the session store or causing other users' session records to be
    +evicted.
    +
    +The built-in session backends now create a session record only if the session
    +is actually modified; empty session records are not created. Thus this
    +potential DoS is now only possible if the site chooses to expose a
    +session-modifying view to anonymous users.
    +
    +As each built-in session backend was fixed separately (rather than a fix in the
    +core sessions framework), maintainers of third-party session backends should
    +check whether the same vulnerability is present in their backend and correct
    +it if so.
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

19

News mentions

0

No linked articles in our index yet.