Skip to content

Commit

Permalink
Fixed #28693 -- Fixed crash in CsrfViewMiddleware when an HTTPS reque…
Browse files Browse the repository at this point in the history
…st has an invalid host.
  • Loading branch information
Tomer Chachamu authored and timgraham committed Feb 15, 2018
1 parent ff55179 commit 7ec0fdf
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
19 changes: 11 additions & 8 deletions django/middleware/csrf.py
Expand Up @@ -10,7 +10,7 @@
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
Expand Down Expand Up @@ -262,14 +262,17 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
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()

# Here we generate a list of all acceptable HTTP referers,
# including the current host since that has been validated
# upstream.
try:
# request.get_host() includes the port.
good_referer = request.get_host()
except DisallowedHost:
pass

# 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()
Expand Down
13 changes: 13 additions & 0 deletions tests/csrf_tests/tests.py
Expand Up @@ -294,6 +294,19 @@ def test_https_bad_referer(self):
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):
"""
Expand Down

0 comments on commit 7ec0fdf

Please sign in to comment.