Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from Feb 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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