+54
-9
lines changedFilter options
+54
-9
lines changed Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ def load(self):
25
25
session_data = None
26
26
if session_data is not None:
27
27
return session_data
28
-
self.create()
28
+
self._session_key = None
29
29
return {}
30
30
31
31
def create(self):
@@ -45,6 +45,8 @@ def create(self):
45
45
raise RuntimeError("Unable to create a new session key.")
46
46
47
47
def save(self, must_create=False):
48
+
if self.session_key is None:
49
+
return self.create()
48
50
if must_create:
49
51
func = self._cache.add
50
52
else:
@@ -56,7 +58,7 @@ def save(self, must_create=False):
56
58
raise CreateError
57
59
58
60
def exists(self, session_key):
59
-
return (KEY_PREFIX + session_key) in self._cache
61
+
return session_key and (KEY_PREFIX + session_key) in self._cache
60
62
61
63
def delete(self, session_key=None):
62
64
if session_key is None:
Original file line number Diff line number Diff line change
@@ -30,11 +30,12 @@ def load(self):
30
30
data = None
31
31
if data is None:
32
32
data = super(SessionStore, self).load()
33
-
cache.set(self.cache_key, data, settings.SESSION_COOKIE_AGE)
33
+
if self.session_key:
34
+
cache.set(self.cache_key, data, settings.SESSION_COOKIE_AGE)
34
35
return data
35
36
36
37
def exists(self, session_key):
37
-
if (KEY_PREFIX + session_key) in cache:
38
+
if session_key and (KEY_PREFIX + session_key) in cache:
38
39
return True
39
40
return super(SessionStore, self).exists(session_key)
40
41
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ def load(self):
20
20
)
21
21
return self.decode(force_unicode(s.session_data))
22
22
except (Session.DoesNotExist, SuspiciousOperation):
23
-
self.create()
23
+
self._session_key = None
24
24
return {}
25
25
26
26
def exists(self, session_key):
@@ -37,7 +37,6 @@ def create(self):
37
37
# Key wasn't unique. Try again.
38
38
continue
39
39
self.modified = True
40
-
self._session_cache = {}
41
40
return
42
41
43
42
def save(self, must_create=False):
@@ -47,6 +46,8 @@ def save(self, must_create=False):
47
46
create a *new* entry (as opposed to possibly updating an existing
48
47
entry).
49
48
"""
49
+
if self.session_key is None:
50
+
return self.create()
50
51
obj = Session(
51
52
session_key=self._get_or_create_session_key(),
52
53
session_data=self.encode(self._get_session(no_load=must_create)),
Original file line number Diff line number Diff line change
@@ -56,11 +56,11 @@ def load(self):
56
56
try:
57
57
session_data = self.decode(file_data)
58
58
except (EOFError, SuspiciousOperation):
59
-
self.create()
59
+
self._session_key = None
60
60
finally:
61
61
session_file.close()
62
62
except IOError:
63
-
self.create()
63
+
self._session_key = None
64
64
return session_data
65
65
66
66
def create(self):
@@ -71,10 +71,11 @@ def create(self):
71
71
except CreateError:
72
72
continue
73
73
self.modified = True
74
-
self._session_cache = {}
75
74
return
76
75
77
76
def save(self, must_create=False):
77
+
if self.session_key is None:
78
+
return self.create()
78
79
# Get the session data now, before we start messing
79
80
# with the file it is stored within.
80
81
session_data = self._get_session(no_load=must_create)
Original file line number Diff line number Diff line change
@@ -162,6 +162,11 @@ def test_cycle(self):
162
162
self.assertNotEqual(self.session.session_key, prev_key)
163
163
self.assertEqual(self.session.items(), prev_data)
164
164
165
+
def test_save_doesnt_clear_data(self):
166
+
self.session['a'] = 'b'
167
+
self.session.save()
168
+
self.assertEqual(self.session['a'], 'b')
169
+
165
170
def test_invalid_key(self):
166
171
# Submitting an invalid session key (either by guessing, or if the db has
167
172
# removed the key) results in a new key being generated.
@@ -256,6 +261,20 @@ def test_decode(self):
256
261
encoded = self.session.encode(data)
257
262
self.assertEqual(self.session.decode(encoded), data)
258
263
264
+
def test_session_load_does_not_create_record(self):
265
+
"""
266
+
Loading an unknown session key does not create a session record.
267
+
268
+
Creating session records on load is a DOS vulnerability.
269
+
"""
270
+
if self.backend is CookieSession:
271
+
raise unittest.SkipTest("Cookie backend doesn't have an external store to create records in.")
272
+
session = self.backend('deadbeef')
273
+
session.load()
274
+
275
+
self.assertFalse(session.exists(session.session_key))
276
+
# provided unknown key was cycled, not reused
277
+
self.assertNotEqual(session.session_key, 'deadbeef')
259
278
260
279
class DatabaseSessionTests(SessionTestsMixin, TestCase):
261
280
Original file line number Diff line number Diff line change
@@ -5,3 +5,24 @@ Django 1.4.21 release notes
5
5
*July 8, 2015*
6
6
7
7
Django 1.4.21 fixes several security issues in 1.4.20.
8
+
9
+
Denial-of-service possibility by filling session store
10
+
======================================================
11
+
12
+
In previous versions of Django, the session backends created a new empty record
13
+
in the session storage anytime ``request.session`` was accessed and there was a
14
+
session key provided in the request cookies that didn't already have a session
15
+
record. This could allow an attacker to easily create many new session records
16
+
simply by sending repeated requests with unknown session keys, potentially
17
+
filling up the session store or causing other users' session records to be
18
+
evicted.
19
+
20
+
The built-in session backends now create a session record only if the session
21
+
is actually modified; empty session records are not created. Thus this
22
+
potential DoS is now only possible if the site chooses to expose a
23
+
session-modifying view to anonymous users.
24
+
25
+
As each built-in session backend was fixed separately (rather than a fix in the
26
+
core sessions framework), maintainers of third-party session backends should
27
+
check whether the same vulnerability is present in their backend and correct
28
+
it if so.
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4