Fixed #28693 -- Fixed crash in CsrfViewMiddleware when an HTTPS request has an invalid host.

This commit is contained in:
Tomer Chachamu 2017-10-22 00:56:01 +01:00 committed by Tim Graham
parent ff5517988a
commit 7ec0fdf62a
2 changed files with 23 additions and 7 deletions

View File

@ -10,7 +10,7 @@ import string
from urllib.parse import urlparse from urllib.parse import urlparse
from django.conf import settings 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.urls import get_callable
from django.utils.cache import patch_vary_headers from django.utils.cache import patch_vary_headers
from django.utils.crypto import constant_time_compare, get_random_string 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'): if server_port not in ('443', '80'):
good_referer = '%s:%s' % (good_referer, server_port) good_referer = '%s:%s' % (good_referer, server_port)
else: else:
# request.get_host() includes the port. try:
good_referer = request.get_host() # request.get_host() includes the port.
good_referer = request.get_host()
except DisallowedHost:
pass
# Here we generate a list of all acceptable HTTP referers, # Create a list of all acceptable HTTP referers, including the
# including the current host since that has been validated # current host if it's permitted by ALLOWED_HOSTS.
# upstream.
good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) 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): if not any(is_same_domain(referer.netloc, host) for host in good_hosts):
reason = REASON_BAD_REFERER % referer.geturl() reason = REASON_BAD_REFERER % referer.geturl()

View File

@ -294,6 +294,19 @@ class CsrfViewMiddlewareTestMixin:
status_code=403, 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) @override_settings(DEBUG=True)
def test_https_malformed_referer(self): def test_https_malformed_referer(self):
""" """