+36
-1
lines changedFilter options
+36
-1
lines changed Original file line number Diff line number Diff line change
@@ -50,7 +50,8 @@
50
50
51
51
from django.conf import settings
52
52
from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS
53
-
from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age
53
+
from django.utils.cache import (get_cache_key, get_max_age, has_vary_header,
54
+
learn_cache_key, patch_response_headers)
54
55
55
56
56
57
class UpdateCacheMiddleware(object):
@@ -93,8 +94,15 @@ def process_response(self, request, response):
93
94
if not self._should_update_cache(request, response):
94
95
# We don't need to update the cache, just return.
95
96
return response
97
+
96
98
if response.streaming or response.status_code != 200:
97
99
return response
100
+
101
+
# Don't cache responses that set a user-specific (and maybe security
102
+
# sensitive) cookie in response to a cookie-less request.
103
+
if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'):
104
+
return response
105
+
98
106
# Try to get the timeout from the "max-age" section of the "Cache-
99
107
# Control" header before reverting to using the default cache_timeout
100
108
# length.
Original file line number Diff line number Diff line change
@@ -18,11 +18,13 @@
18
18
from django.core.cache import get_cache
19
19
from django.core.cache.backends.base import (CacheKeyWarning,
20
20
InvalidCacheBackendError)
21
+
from django.core.context_processors import csrf
21
22
from django.db import router
22
23
from django.http import (HttpResponse, HttpRequest, StreamingHttpResponse,
23
24
QueryDict)
24
25
from django.middleware.cache import (FetchFromCacheMiddleware,
25
26
UpdateCacheMiddleware, CacheMiddleware)
27
+
from django.middleware.csrf import CsrfViewMiddleware
26
28
from django.template import Template
27
29
from django.template.response import TemplateResponse
28
30
from django.test import TestCase, TransactionTestCase, RequestFactory
@@ -1456,6 +1458,10 @@ def hello_world_view(request, value):
1456
1458
return HttpResponse('Hello World %s' % value)
1457
1459
1458
1460
1461
+
def csrf_view(request):
1462
+
return HttpResponse(csrf(request)['csrf_token'])
1463
+
1464
+
1459
1465
@override_settings(
1460
1466
CACHE_MIDDLEWARE_ALIAS='other',
1461
1467
CACHE_MIDDLEWARE_KEY_PREFIX='middlewareprefix',
@@ -1696,6 +1702,27 @@ def test_view_decorator(self):
1696
1702
response = other_with_timeout_view(request, '18')
1697
1703
self.assertEqual(response.content, b'Hello World 18')
1698
1704
1705
+
def test_sensitive_cookie_not_cached(self):
1706
+
"""
1707
+
Django must prevent caching of responses that set a user-specific (and
1708
+
maybe security sensitive) cookie in response to a cookie-less request.
1709
+
"""
1710
+
csrf_middleware = CsrfViewMiddleware()
1711
+
cache_middleware = CacheMiddleware()
1712
+
1713
+
request = self.factory.get('/view/')
1714
+
self.assertIsNone(cache_middleware.process_request(request))
1715
+
1716
+
csrf_middleware.process_view(request, csrf_view, (), {})
1717
+
1718
+
response = csrf_view(request)
1719
+
1720
+
response = csrf_middleware.process_response(request, response)
1721
+
response = cache_middleware.process_response(request, response)
1722
+
1723
+
# Inserting a CSRF cookie in a cookie-less request prevented caching.
1724
+
self.assertIsNone(cache_middleware.process_request(request))
1725
+
1699
1726
1700
1727
@override_settings(
1701
1728
CACHE_MIDDLEWARE_KEY_PREFIX='settingsprefix',
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