Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -505,6 +505,7 @@ answer newbie questions, and generally made Django that much better: Bernd Schlapsi schwank@gmail.com scott@staplefish.com Olivier Sels <olivier.sels@gmail.com> Ilya Semenov <semenov@inetss.com> Aleksandra Sendecka <asendecka@hauru.eu> serbaut@gmail.com Loading django/middleware/csrf.py +7 −27 Original line number Diff line number Diff line Loading @@ -83,6 +83,13 @@ class CsrfViewMiddleware(object): return None def _reject(self, request, reason): logger.warning('Forbidden (%s): %s', reason, request.path, extra={ 'status_code': 403, 'request': request, } ) return _get_failure_view()(request, reason=reason) def process_view(self, request, callback, callback_args, callback_kwargs): Loading Loading @@ -134,38 +141,18 @@ class CsrfViewMiddleware(object): # we can use strict Referer checking. referer = request.META.get('HTTP_REFERER') if referer is None: logger.warning('Forbidden (%s): %s', REASON_NO_REFERER, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_REFERER) # Note that request.get_host() includes the port. good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) logger.warning('Forbidden (%s): %s', reason, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, reason) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. logger.warning('Forbidden (%s): %s', REASON_NO_CSRF_COOKIE, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. Loading @@ -179,13 +166,6 @@ class CsrfViewMiddleware(object): request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): logger.warning('Forbidden (%s): %s', REASON_BAD_TOKEN, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_BAD_TOKEN) return self._accept(request) Loading django/views/decorators/csrf.py +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ using the decorator multiple times, is harmless and efficient. class _EnsureCsrfToken(CsrfViewMiddleware): # We need this to behave just like the CsrfViewMiddleware, but not reject # requests. # requests or log warnings. def _reject(self, request, reason): return None Loading tests/csrf_tests/tests.py +39 −12 Original line number Diff line number Diff line # -*- coding: utf-8 -*- from __future__ import unicode_literals import logging from django.conf import settings from django.core.context_processors import csrf Loading Loading @@ -353,3 +354,29 @@ class CsrfViewMiddlewareTest(TestCase): resp2 = CsrfViewMiddleware().process_response(req, resp) self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)) self.assertTrue('Cookie' in resp2.get('Vary','')) def test_ensures_csrf_cookie_no_logging(self): """ Tests that ensure_csrf_cookie doesn't log warnings. See #19436. """ @ensure_csrf_cookie def view(request): # Doesn't insert a token or anything return HttpResponse(content="") class TestHandler(logging.Handler): def emit(self, record): raise Exception("This shouldn't have happened!") logger = logging.getLogger('django.request') test_handler = TestHandler() old_log_level = logger.level try: logger.addHandler(test_handler) logger.setLevel(logging.WARNING) req = self._get_GET_no_csrf_cookie_request() resp = view(req) finally: logger.removeHandler(test_handler) logger.setLevel(old_log_level) Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -505,6 +505,7 @@ answer newbie questions, and generally made Django that much better: Bernd Schlapsi schwank@gmail.com scott@staplefish.com Olivier Sels <olivier.sels@gmail.com> Ilya Semenov <semenov@inetss.com> Aleksandra Sendecka <asendecka@hauru.eu> serbaut@gmail.com Loading
django/middleware/csrf.py +7 −27 Original line number Diff line number Diff line Loading @@ -83,6 +83,13 @@ class CsrfViewMiddleware(object): return None def _reject(self, request, reason): logger.warning('Forbidden (%s): %s', reason, request.path, extra={ 'status_code': 403, 'request': request, } ) return _get_failure_view()(request, reason=reason) def process_view(self, request, callback, callback_args, callback_kwargs): Loading Loading @@ -134,38 +141,18 @@ class CsrfViewMiddleware(object): # we can use strict Referer checking. referer = request.META.get('HTTP_REFERER') if referer is None: logger.warning('Forbidden (%s): %s', REASON_NO_REFERER, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_REFERER) # Note that request.get_host() includes the port. good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) logger.warning('Forbidden (%s): %s', reason, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, reason) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. logger.warning('Forbidden (%s): %s', REASON_NO_CSRF_COOKIE, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. Loading @@ -179,13 +166,6 @@ class CsrfViewMiddleware(object): request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): logger.warning('Forbidden (%s): %s', REASON_BAD_TOKEN, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_BAD_TOKEN) return self._accept(request) Loading
django/views/decorators/csrf.py +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ using the decorator multiple times, is harmless and efficient. class _EnsureCsrfToken(CsrfViewMiddleware): # We need this to behave just like the CsrfViewMiddleware, but not reject # requests. # requests or log warnings. def _reject(self, request, reason): return None Loading
tests/csrf_tests/tests.py +39 −12 Original line number Diff line number Diff line # -*- coding: utf-8 -*- from __future__ import unicode_literals import logging from django.conf import settings from django.core.context_processors import csrf Loading Loading @@ -353,3 +354,29 @@ class CsrfViewMiddlewareTest(TestCase): resp2 = CsrfViewMiddleware().process_response(req, resp) self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)) self.assertTrue('Cookie' in resp2.get('Vary','')) def test_ensures_csrf_cookie_no_logging(self): """ Tests that ensure_csrf_cookie doesn't log warnings. See #19436. """ @ensure_csrf_cookie def view(request): # Doesn't insert a token or anything return HttpResponse(content="") class TestHandler(logging.Handler): def emit(self, record): raise Exception("This shouldn't have happened!") logger = logging.getLogger('django.request') test_handler = TestHandler() old_log_level = logger.level try: logger.addHandler(test_handler) logger.setLevel(logging.WARNING) req = self._get_GET_no_csrf_cookie_request() resp = view(req) finally: logger.removeHandler(test_handler) logger.setLevel(old_log_level)