Skip to content

Commit

Permalink
Fixed #20338 -- Stripped ending dot during host validation
Browse files Browse the repository at this point in the history
Thanks manfre for the report and Timo Graham for the review.
  • Loading branch information
claudep committed Oct 24, 2013
1 parent 08c9ab5 commit c052699
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
2 changes: 2 additions & 0 deletions django/http/request.py
Expand Up @@ -520,6 +520,8 @@ def validate_host(host, allowed_hosts):
Return ``True`` for a valid host, ``False`` otherwise.
"""
host = host[:-1] if host.endswith('.') else host

for pattern in allowed_hosts:
pattern = pattern.lower()
match = (
Expand Down
14 changes: 9 additions & 5 deletions docs/ref/settings.txt
Expand Up @@ -79,18 +79,22 @@ responsible to provide your own validation of the ``Host`` header (perhaps in a
middleware; if so this middleware must be listed first in
:setting:`MIDDLEWARE_CLASSES`).

.. note::
.. versionchanged:: 1.7

If you want to also allow the `fully qualified domain name (FQDN)`_, which
some browsers can send in the Host header, you must explicitly add another
ALLOWED_HOSTS entry that includes a trailing period. This entry can also be
a subdomain wildcard::
In previous versions of Django, if you wanted to also allow the
`fully qualified domain name (FQDN)`_, which some browsers can send in the
``Host`` header, you had to explicitly add another ``ALLOWED_HOSTS`` entry
that included a trailing period. This entry could also be a subdomain
wildcard::

ALLOWED_HOSTS = [
'.example.com', # Allow domain and subdomains
'.example.com.', # Also allow FQDN and subdomains
]

In Django 1.7, the trailing dot is stripped when performing host validation,
thus an entry with a trailing dot isn't required.

.. _`fully qualified domain name (FQDN)`: http://en.wikipedia.org/wiki/Fully_qualified_domain_name

If the ``Host`` header (or ``X-Forwarded-Host`` if
Expand Down
4 changes: 3 additions & 1 deletion tests/requests/tests.py
Expand Up @@ -529,6 +529,8 @@ def test_http_get_host(self):
'anything.multitenant.com',
'multitenant.com',
'insensitive.com',
'example.com.',
'example.com.:80',
]

for host in legit_hosts:
Expand All @@ -539,7 +541,7 @@ def test_http_get_host(self):
request.get_host()

# Poisoned host headers are rejected as suspicious
for host in chain(self.poisoned_hosts, ['other.com']):
for host in chain(self.poisoned_hosts, ['other.com', 'example.com..']):
with self.assertRaises(SuspiciousOperation):
request = HttpRequest()
request.META = {
Expand Down

0 comments on commit c052699

Please sign in to comment.