From 7ec0fdf62afd565dd9a888300e7e33d0bf3e5fd5 Mon Sep 17 00:00:00 2001 From: Tomer Chachamu Date: Sun, 22 Oct 2017 00:56:01 +0100 Subject: [PATCH] Fixed #28693 -- Fixed crash in CsrfViewMiddleware when an HTTPS request has an invalid host. --- django/middleware/csrf.py | 17 ++++++++++------- tests/csrf_tests/tests.py | 13 +++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py index ce1329bfa6..a3a6eaf62f 100644 --- a/django/middleware/csrf.py +++ b/django/middleware/csrf.py @@ -10,7 +10,7 @@ import string from urllib.parse import urlparse from django.conf import settings -from django.core.exceptions import ImproperlyConfigured +from django.core.exceptions import DisallowedHost, ImproperlyConfigured from django.urls import get_callable from django.utils.cache import patch_vary_headers from django.utils.crypto import constant_time_compare, get_random_string @@ -262,14 +262,17 @@ class CsrfViewMiddleware(MiddlewareMixin): if server_port not in ('443', '80'): good_referer = '%s:%s' % (good_referer, server_port) else: - # request.get_host() includes the port. - good_referer = request.get_host() + try: + # request.get_host() includes the port. + good_referer = request.get_host() + except DisallowedHost: + pass - # Here we generate a list of all acceptable HTTP referers, - # including the current host since that has been validated - # upstream. + # Create a list of all acceptable HTTP referers, including the + # current host if it's permitted by ALLOWED_HOSTS. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) - good_hosts.append(good_referer) + if good_referer is not None: + good_hosts.append(good_referer) if not any(is_same_domain(referer.netloc, host) for host in good_hosts): reason = REASON_BAD_REFERER % referer.geturl() diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index 7c1e62c504..8a9c509f4c 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -294,6 +294,19 @@ class CsrfViewMiddlewareTestMixin: status_code=403, ) + def test_https_malformed_host(self): + """ + CsrfViewMiddleware generates a 403 response if it receives an HTTPS + request with a bad host. + """ + req = self._get_GET_no_csrf_cookie_request() + req._is_secure_override = True + req.META['HTTP_HOST'] = '@malformed' + req.META['HTTP_REFERER'] = 'https://www.evil.org/somepage' + req.META['SERVER_PORT'] = '443' + response = self.mw.process_view(req, token_view, (), {}) + self.assertEqual(response.status_code, 403) + @override_settings(DEBUG=True) def test_https_malformed_referer(self): """