mirror of
				https://github.com/django/django.git
				synced 2025-11-04 05:35:37 +00:00 
			
		
		
		
	Fixed #19436 -- Don't log warnings in ensure_csrf_cookie.
This commit is contained in:
		
							parent
							
								
									7d050e8e9c
								
							
						
					
					
						commit
						63a9555d57
					
				
					 4 changed files with 48 additions and 40 deletions
				
			
		
							
								
								
									
										1
									
								
								AUTHORS
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
										
									
									
									
								
							| 
						 | 
					@ -505,6 +505,7 @@ answer newbie questions, and generally made Django that much better:
 | 
				
			||||||
    Bernd Schlapsi
 | 
					    Bernd Schlapsi
 | 
				
			||||||
    schwank@gmail.com
 | 
					    schwank@gmail.com
 | 
				
			||||||
    scott@staplefish.com
 | 
					    scott@staplefish.com
 | 
				
			||||||
 | 
					    Olivier Sels <olivier.sels@gmail.com>
 | 
				
			||||||
    Ilya Semenov <semenov@inetss.com>
 | 
					    Ilya Semenov <semenov@inetss.com>
 | 
				
			||||||
    Aleksandra Sendecka <asendecka@hauru.eu>
 | 
					    Aleksandra Sendecka <asendecka@hauru.eu>
 | 
				
			||||||
    serbaut@gmail.com
 | 
					    serbaut@gmail.com
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,13 @@ class CsrfViewMiddleware(object):
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _reject(self, request, reason):
 | 
					    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)
 | 
					        return _get_failure_view()(request, reason=reason)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def process_view(self, request, callback, callback_args, callback_kwargs):
 | 
					    def process_view(self, request, callback, callback_args, callback_kwargs):
 | 
				
			||||||
| 
						 | 
					@ -134,38 +141,18 @@ class CsrfViewMiddleware(object):
 | 
				
			||||||
                # we can use strict Referer checking.
 | 
					                # we can use strict Referer checking.
 | 
				
			||||||
                referer = request.META.get('HTTP_REFERER')
 | 
					                referer = request.META.get('HTTP_REFERER')
 | 
				
			||||||
                if referer is None:
 | 
					                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)
 | 
					                    return self._reject(request, REASON_NO_REFERER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Note that request.get_host() includes the port.
 | 
					                # Note that request.get_host() includes the port.
 | 
				
			||||||
                good_referer = 'https://%s/' % request.get_host()
 | 
					                good_referer = 'https://%s/' % request.get_host()
 | 
				
			||||||
                if not same_origin(referer, good_referer):
 | 
					                if not same_origin(referer, good_referer):
 | 
				
			||||||
                    reason = REASON_BAD_REFERER % (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)
 | 
					                    return self._reject(request, reason)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if csrf_token is None:
 | 
					            if csrf_token is None:
 | 
				
			||||||
                # No CSRF cookie. For POST requests, we insist on a CSRF cookie,
 | 
					                # No CSRF cookie. For POST requests, we insist on a CSRF cookie,
 | 
				
			||||||
                # and in this way we can avoid all CSRF attacks, including login
 | 
					                # and in this way we can avoid all CSRF attacks, including login
 | 
				
			||||||
                # CSRF.
 | 
					                # 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)
 | 
					                return self._reject(request, REASON_NO_CSRF_COOKIE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Check non-cookie token for match.
 | 
					            # Check non-cookie token for match.
 | 
				
			||||||
| 
						 | 
					@ -179,13 +166,6 @@ class CsrfViewMiddleware(object):
 | 
				
			||||||
                request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
 | 
					                request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not constant_time_compare(request_csrf_token, csrf_token):
 | 
					            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._reject(request, REASON_BAD_TOKEN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return self._accept(request)
 | 
					        return self._accept(request)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ using the decorator multiple times, is harmless and efficient.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _EnsureCsrfToken(CsrfViewMiddleware):
 | 
					class _EnsureCsrfToken(CsrfViewMiddleware):
 | 
				
			||||||
    # We need this to behave just like the CsrfViewMiddleware, but not reject
 | 
					    # We need this to behave just like the CsrfViewMiddleware, but not reject
 | 
				
			||||||
    # requests.
 | 
					    # requests or log warnings.
 | 
				
			||||||
    def _reject(self, request, reason):
 | 
					    def _reject(self, request, reason):
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
from __future__ import unicode_literals
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.core.context_processors import csrf
 | 
					from django.core.context_processors import csrf
 | 
				
			||||||
| 
						 | 
					@ -353,3 +354,29 @@ class CsrfViewMiddlewareTest(TestCase):
 | 
				
			||||||
        resp2 = CsrfViewMiddleware().process_response(req, resp)
 | 
					        resp2 = CsrfViewMiddleware().process_response(req, resp)
 | 
				
			||||||
        self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False))
 | 
					        self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False))
 | 
				
			||||||
        self.assertTrue('Cookie' in resp2.get('Vary',''))
 | 
					        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…
	
	Add table
		Add a link
		
	
		Reference in a new issue