From 22e8ab02863819093832de9f771bf40a62a6bd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Sat, 1 Sep 2018 16:32:35 +0200 Subject: [PATCH] Fixed #29728 -- Prevented session resaving if CSRF cookie is unchanged. --- django/middleware/csrf.py | 3 ++- tests/csrf_tests/tests.py | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py index 98830f7774..c9c27666ae 100644 --- a/django/middleware/csrf.py +++ b/django/middleware/csrf.py @@ -181,7 +181,8 @@ class CsrfViewMiddleware(MiddlewareMixin): def _set_token(self, request, response): if settings.CSRF_USE_SESSIONS: - request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE'] + if request.session.get(CSRF_SESSION_KEY) != request.META['CSRF_COOKIE']: + request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE'] else: response.set_cookie( settings.CSRF_COOKIE_NAME, diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index 9bebb7ed8f..2c40e44ae1 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -1,6 +1,7 @@ import re from django.conf import settings +from django.contrib.sessions.backends.cache import SessionStore from django.core.exceptions import ImproperlyConfigured from django.http import HttpRequest from django.middleware.csrf import ( @@ -24,8 +25,7 @@ class TestingHttpRequest(HttpRequest): """ def __init__(self): super().__init__() - # A real session backend isn't needed. - self.session = {} + self.session = SessionStore() def is_secure(self): return getattr(self, '_is_secure_override', False) @@ -693,6 +693,19 @@ class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTest ensure_csrf_cookie_view(req) self.assertTrue(req.session.get(CSRF_SESSION_KEY, False)) + def test_session_modify(self): + """The session isn't saved if the CSRF cookie is unchanged.""" + req = self._get_GET_no_csrf_cookie_request() + self.mw.process_view(req, ensure_csrf_cookie_view, (), {}) + resp = ensure_csrf_cookie_view(req) + self.mw.process_response(req, resp) + self.assertIsNotNone(req.session.get(CSRF_SESSION_KEY)) + req.session.modified = False + self.mw.process_view(req, ensure_csrf_cookie_view, (), {}) + resp = ensure_csrf_cookie_view(req) + self.mw.process_response(req, resp) + self.assertFalse(req.session.modified) + def test_ensures_csrf_cookie_with_middleware(self): """ The ensure_csrf_cookie() decorator works with the CsrfViewMiddleware