Commit 17e66164 authored by Tobias McNulty's avatar Tobias McNulty Committed by Tim Graham
Browse files

Refs #26666 -- Added ALLOWED_HOSTS validation when running tests.

Also used ALLOWED_HOSTS to check for external hosts in assertRedirects().
parent 00551c3e
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ from django.core.servers.basehttp import WSGIRequestHandler, WSGIServer
from django.db import DEFAULT_DB_ALIAS, connection, connections, transaction
from django.forms.fields import CharField
from django.http import QueryDict
from django.http.request import split_domain_port, validate_host
from django.test.client import Client
from django.test.html import HTMLParseError, parse_html
from django.test.signals import setting_changed, template_rendered
@@ -306,10 +307,13 @@ class SimpleTestCase(unittest.TestCase):
                # netloc might be empty, or in cases where Django tests the
                # HTTP scheme, the convention is for netloc to be 'testserver'.
                # Trust both as "internal" URLs here.
                if netloc and netloc != 'testserver':
                domain, port = split_domain_port(netloc)
                if domain and not validate_host(domain, settings.ALLOWED_HOSTS):
                    raise ValueError(
                        "The Django test client is unable to fetch remote URLs (got %s). "
                        "Use assertRedirects(..., fetch_redirect_response=False) instead." % url
                        "The test client is unable to fetch remote URLs (got %s). "
                        "If the host is served by Django, add '%s' to ALLOWED_HOSTS. "
                        "Otherwise, use assertRedirects(..., fetch_redirect_response=False)."
                        % (url, domain)
                    )
                redirect_response = response.client.get(path, QueryDict(query), secure=(scheme == 'https'))

@@ -1324,9 +1328,12 @@ class LiveServerTestCase(TransactionTestCase):
                conn.allow_thread_sharing = True
                connections_override[conn.alias] = conn

        # Launch the live server's thread
        specified_address = os.environ.get(
            'DJANGO_LIVE_TEST_SERVER_ADDRESS', 'localhost:8081-8179')
        cls._live_server_modified_settings = modify_settings(
            ALLOWED_HOSTS={'append': specified_address.split(':')[0]},
        )
        cls._live_server_modified_settings.enable()

        # The specified ports may be of the form '8000-8010,8080,9200-9300'
        # i.e. a comma-separated list of ports or ranges of ports, so we break
@@ -1348,6 +1355,7 @@ class LiveServerTestCase(TransactionTestCase):
        except Exception:
            msg = 'Invalid address ("%s") for live server.' % specified_address
            six.reraise(ImproperlyConfigured, ImproperlyConfigured(msg), sys.exc_info()[2])
        # Launch the live server's thread
        cls.server_thread = cls._create_server_thread(host, possible_ports, connections_override)
        cls.server_thread.daemon = True
        cls.server_thread.start()
@@ -1386,6 +1394,7 @@ class LiveServerTestCase(TransactionTestCase):
    @classmethod
    def tearDownClass(cls):
        cls._tearDownClassInternal()
        cls._live_server_modified_settings.disable()
        super(LiveServerTestCase, cls).tearDownClass()


+2 −1
Original line number Diff line number Diff line
@@ -111,7 +111,8 @@ def setup_test_environment():
    settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

    request._original_allowed_hosts = settings.ALLOWED_HOSTS
    settings.ALLOWED_HOSTS = ['*']
    # Add the default host of the test client.
    settings.ALLOWED_HOSTS = settings.ALLOWED_HOSTS + ['testserver']

    mail.outbox = []

+7 −3
Original line number Diff line number Diff line
@@ -90,14 +90,18 @@ If the ``Host`` header (or ``X-Forwarded-Host`` if
list, the :meth:`django.http.HttpRequest.get_host()` method will raise
:exc:`~django.core.exceptions.SuspiciousOperation`.

When :setting:`DEBUG` is ``True`` or when running tests, host validation is
disabled; any host will be accepted. Thus it's usually only necessary to set it
in production.
When :setting:`DEBUG` is ``True``, host validation is disabled; any host will
be accepted. ``ALLOWED_HOSTS`` is :ref:`checked when running tests
<topics-testing-advanced-multiple-hosts>`.

This validation only applies via :meth:`~django.http.HttpRequest.get_host()`;
if your code accesses the ``Host`` header directly from ``request.META`` you
are bypassing this security protection.

.. versionchanged:: 1.11

    In older versions, ``ALLOWED_HOSTS`` wasn't checked when running tests.

.. setting:: APPEND_SLASH

``APPEND_SLASH``
+5 −0
Original line number Diff line number Diff line
@@ -262,6 +262,11 @@ Miscellaneous
* CSRF failures are logged to the ``django.security.csrf ``` logger instead of
  ``django.request``.

* :setting:`ALLOWED_HOSTS` validation is no longer disabled when running tests.
  If your application includes tests with custom host names, you must include
  those host names in :setting:`ALLOWED_HOSTS`. See
  :ref:`topics-testing-advanced-multiple-hosts`.

* Using a foreign key's id (e.g. ``'field_id'``) in ``ModelAdmin.list_display``
  displays the related object's ID. Remove the ``_id`` suffix if you want the
  old behavior of the string representation of the object.
+1 −0
Original line number Diff line number Diff line
@@ -498,6 +498,7 @@ multiline
multilinestring
multipart
multipolygon
multitenancy
multithreaded
multithreading
Mumbai
Loading