A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/45acd6d836895a4c36575f48b3fb36a3dae98d19 below:

[1.9.x] Fixed CVE-2016-9014 -- Validated Host header when DEBUG=True. · django/django@45acd6d · GitHub

File tree Expand file treeCollapse file tree 5 files changed

+71

-21

lines changed

Filter options

Expand file treeCollapse file tree 5 files changed

+71

-21

lines changed Original file line number Diff line number Diff line change

@@ -92,12 +92,13 @@ def get_host(self):

92 92

"""Return the HTTP host using the environment or request headers."""

93 93

host = self._get_raw_host()

94 94 95 -

# There is no hostname validation when DEBUG=True

96 -

if settings.DEBUG:

97 -

return host

95 +

# Allow variants of localhost if ALLOWED_HOSTS is empty and DEBUG=True.

96 +

allowed_hosts = settings.ALLOWED_HOSTS

97 +

if settings.DEBUG and not allowed_hosts:

98 +

allowed_hosts = ['localhost', '127.0.0.1', '[::1]']

98 99 99 100

domain, port = split_domain_port(host)

100 -

if domain and validate_host(domain, settings.ALLOWED_HOSTS):

101 +

if domain and validate_host(domain, allowed_hosts):

101 102

return host

102 103

else:

103 104

msg = "Invalid HTTP_HOST header: %r." % host

Original file line number Diff line number Diff line change

@@ -90,14 +90,18 @@ If the ``Host`` header (or ``X-Forwarded-Host`` if

90 90

list, the :meth:`django.http.HttpRequest.get_host()` method will raise

91 91

:exc:`~django.core.exceptions.SuspiciousOperation`.

92 92 93 -

When :setting:`DEBUG` is ``True`` or when running tests, host validation is

94 -

disabled; any host will be accepted. Thus it's usually only necessary to set it

95 -

in production.

93 +

When :setting:`DEBUG` is ``True`` and ``ALLOWED_HOSTS`` is empty, the host

94 +

is validated against ``['localhost', '127.0.0.1', '[::1]']``.

96 95 97 96

This validation only applies via :meth:`~django.http.HttpRequest.get_host()`;

98 97

if your code accesses the ``Host`` header directly from ``request.META`` you

99 98

are bypassing this security protection.

100 99 100 +

.. versionchanged:: 1.9.11

101 + 102 +

In older versions, ``ALLOWED_HOSTS`` wasn't checked if ``DEBUG=True``.

103 +

This was also changed in Django 1.8.16 to prevent a DNS rebinding attack.

104 + 101 105

.. setting:: ALLOWED_INCLUDE_ROOTS

102 106 103 107

ALLOWED_INCLUDE_ROOTS

Original file line number Diff line number Diff line change

@@ -19,3 +19,25 @@ the ``manage.py test --keepdb`` option or if the user has an active session

19 19

(such as an attacker's connection).

20 20 21 21

A randomly generated password is now used for each test run.

22 + 23 +

DNS rebinding vulnerability when ``DEBUG=True``

24 +

===============================================

25 + 26 +

Older versions of Django don't validate the ``Host`` header against

27 +

``settings.ALLOWED_HOSTS`` when ``settings.DEBUG=True``. This makes them

28 +

vulnerable to a `DNS rebinding attack

29 +

<http://benmmurphy.github.io/blog/2016/07/11/rails-webconsole-dns-rebinding/>`_.

30 + 31 +

While Django doesn't ship a module that allows remote code execution, this is

32 +

at least a cross-site scripting vector, which could be quite serious if

33 +

developers load a copy of the production database in development or connect to

34 +

some production services for which there's no development instance, for

35 +

example. If a project uses a package like the ``django-debug-toolbar``, then

36 +

the attacker could execute arbitrary SQL, which could be especially bad if the

37 +

developers connect to the database with a superuser account.

38 + 39 +

``settings.ALLOWED_HOSTS`` is now validated regardless of ``DEBUG``. For

40 +

convenience, if ``ALLOWED_HOSTS`` is empty and ``DEBUG=True``, the following

41 +

variations of localhost are allowed ``['localhost', '127.0.0.1', '::1']``. If

42 +

your local settings file has your production ``ALLOWED_HOSTS`` value, you must

43 +

now omit it to get those fallback values.

Original file line number Diff line number Diff line change

@@ -19,3 +19,25 @@ the ``manage.py test --keepdb`` option or if the user has an active session

19 19

(such as an attacker's connection).

20 20 21 21

A randomly generated password is now used for each test run.

22 + 23 +

DNS rebinding vulnerability when ``DEBUG=True``

24 +

===============================================

25 + 26 +

Older versions of Django don't validate the ``Host`` header against

27 +

``settings.ALLOWED_HOSTS`` when ``settings.DEBUG=True``. This makes them

28 +

vulnerable to a `DNS rebinding attack

29 +

<http://benmmurphy.github.io/blog/2016/07/11/rails-webconsole-dns-rebinding/>`_.

30 + 31 +

While Django doesn't ship a module that allows remote code execution, this is

32 +

at least a cross-site scripting vector, which could be quite serious if

33 +

developers load a copy of the production database in development or connect to

34 +

some production services for which there's no development instance, for

35 +

example. If a project uses a package like the ``django-debug-toolbar``, then

36 +

the attacker could execute arbitrary SQL, which could be especially bad if the

37 +

developers connect to the database with a superuser account.

38 + 39 +

``settings.ALLOWED_HOSTS`` is now validated regardless of ``DEBUG``. For

40 +

convenience, if ``ALLOWED_HOSTS`` is empty and ``DEBUG=True``, the following

41 +

variations of localhost are allowed ``['localhost', '127.0.0.1', '::1']``. If

42 +

your local settings file has your production ``ALLOWED_HOSTS`` value, you must

43 +

now omit it to get those fallback values.

Original file line number Diff line number Diff line change

@@ -709,21 +709,22 @@ def test_get_port_with_x_forwarded_port(self):

709 709

self.assertEqual(request.get_port(), '8080')

710 710 711 711

@override_settings(DEBUG=True, ALLOWED_HOSTS=[])

712 -

def test_host_validation_disabled_in_debug_mode(self):

713 -

"""If ALLOWED_HOSTS is empty and DEBUG is True, all hosts pass."""

714 -

request = HttpRequest()

715 -

request.META = {

716 -

'HTTP_HOST': 'example.com',

717 -

}

718 -

self.assertEqual(request.get_host(), 'example.com')

712 +

def test_host_validation_in_debug_mode(self):

713 +

"""

714 +

If ALLOWED_HOSTS is empty and DEBUG is True, variants of localhost are

715 +

allowed.

716 +

"""

717 +

valid_hosts = ['localhost', '127.0.0.1', '[::1]']

718 +

for host in valid_hosts:

719 +

request = HttpRequest()

720 +

request.META = {'HTTP_HOST': host}

721 +

self.assertEqual(request.get_host(), host)

719 722 720 -

# Invalid hostnames would normally raise a SuspiciousOperation,

721 -

# but we have DEBUG=True, so this check is disabled.

722 -

request = HttpRequest()

723 -

request.META = {

724 -

'HTTP_HOST': "invalid_hostname.com",

725 -

}

726 -

self.assertEqual(request.get_host(), "invalid_hostname.com")

723 +

# Other hostnames raise a SuspiciousOperation.

724 +

with self.assertRaises(SuspiciousOperation):

725 +

request = HttpRequest()

726 +

request.META = {'HTTP_HOST': 'example.com'}

727 +

request.get_host()

727 728 728 729

@override_settings(ALLOWED_HOSTS=[])

729 730

def test_get_host_suggestion_of_allowed_host(self):

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4