diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/ref/settings.txt | 36 | ||||
| -rw-r--r-- | docs/releases/1.5.txt | 10 | ||||
| -rw-r--r-- | docs/topics/security.txt | 63 |
3 files changed, 74 insertions, 35 deletions
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 25818184f6..bba936d837 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -56,6 +56,42 @@ of (Full name, email address). Example:: Note that Django will email *all* of these people whenever an error happens. See :doc:`/howto/error-reporting` for more information. +.. setting:: ALLOWED_HOSTS + +ALLOWED_HOSTS +------------- + +Default: ``[]`` (Empty list) + +A list of strings representing the host/domain names that this Django site can +serve. This is a security measure to prevent an attacker from poisoning caches +and password reset emails with links to malicious hosts by submitting requests +with a fake HTTP ``Host`` header, which is possible even under many +seemingly-safe webserver configurations. + +Values in this list can be fully qualified names (e.g. ``'www.example.com'``), +in which case they will be matched against the request's ``Host`` header +exactly (case-insensitive, not including port). A value beginning with a period +can be used as a subdomain wildcard: ``'.example.com'`` will match +``example.com``, ``www.example.com``, and any other subdomain of +``example.com``. A value of ``'*'`` will match anything; in this case you are +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`). + +If the ``Host`` header (or ``X-Forwarded-Host`` if +:setting:`USE_X_FORWARDED_HOST` is enabled) does not match any value in this +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. + +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. + .. setting:: ALLOWED_INCLUDE_ROOTS ALLOWED_INCLUDE_ROOTS diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt index 8813313035..63f9758762 100644 --- a/docs/releases/1.5.txt +++ b/docs/releases/1.5.txt @@ -354,6 +354,16 @@ Backwards incompatible changes in 1.5 deprecation timeline for a given feature, its removal may appear as a backwards incompatible change. +``ALLOWED_HOSTS`` required in production +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The new :setting:`ALLOWED_HOSTS` setting validates the request's ``Host`` +header and protects against host-poisoning attacks. This setting is now +required whenever :setting:`DEBUG` is ``False``, or else +:meth:`django.http.HttpRequest.get_host()` will raise +:exc:`~django.core.exceptions.SuspiciousOperation`. For more details see the +:setting:`full documentation<ALLOWED_HOSTS>` for the new setting. + Managers on abstract models ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/topics/security.txt b/docs/topics/security.txt index 07b8ebcdd2..566202eefa 100644 --- a/docs/topics/security.txt +++ b/docs/topics/security.txt @@ -160,47 +160,40 @@ server, there are some additional steps you may need: .. _host-headers-virtual-hosting: -Host headers and virtual hosting -================================ +Host header validation +====================== -Django uses the ``Host`` header provided by the client to construct URLs -in certain cases. While these values are sanitized to prevent Cross -Site Scripting attacks, they can be used for Cross-Site Request -Forgery and cache poisoning attacks in some circumstances. We -recommend you ensure your Web server is configured such that: +Django uses the ``Host`` header provided by the client to construct URLs in +certain cases. While these values are sanitized to prevent Cross Site Scripting +attacks, a fake ``Host`` value can be used for Cross-Site Request Forgery, +cache poisoning attacks, and poisoning links in emails. -* It always validates incoming HTTP ``Host`` headers against the expected - host name. -* Disallows requests with no ``Host`` header. -* Is *not* configured with a catch-all virtual host that forwards requests - to a Django application. +Because even seemingly-secure webserver configurations are susceptible to fake +``Host`` headers, Django validates ``Host`` headers against the +:setting:`ALLOWED_HOSTS` setting in the +:meth:`django.http.HttpRequest.get_host()` method. -Additionally, as of 1.3.1, Django requires you to explicitly enable support for -the ``X-Forwarded-Host`` header if your configuration requires it. +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. + +For more details see the full :setting:`ALLOWED_HOSTS` documentation. -Configuration for Apache ------------------------- +.. warning:: -The easiest way to get the described behavior in Apache is as follows. Create -a `virtual host`_ using the ServerName_ and ServerAlias_ directives to restrict -the domains Apache reacts to. Please keep in mind that while the directives do -support ports the match is only performed against the hostname. This means that -the ``Host`` header could still contain a port pointing to another webserver on -the same machine. The next step is to make sure that your newly created virtual -host is not also the default virtual host. Apache uses the first virtual host -found in the configuration file as default virtual host. As such you have to -ensure that you have another virtual host which will act as catch-all virtual -host. Just add one if you do not have one already, there is nothing special -about it aside from ensuring it is the first virtual host in the configuration -file. Debian/Ubuntu users usually don't have to take any action, since Apache -ships with a default virtual host in ``sites-available`` which is linked into -``sites-enabled`` as ``000-default`` and included from ``apache2.conf``. Just -make sure not to name your site ``000-abc``, since files are included in -alphabetical order. + Previous versions of this document recommended configuring your webserver to + ensure it validates incoming HTTP ``Host`` headers. While this is still + recommended, in many common webservers a configuration that seems to + validate the ``Host`` header may not in fact do so. For instance, even if + Apache is configured such that your Django site is served from a non-default + virtual host with the ``ServerName`` set, it is still possible for an HTTP + request to match this virtual host and supply a fake ``Host`` header. Thus, + Django now requires that you set :setting:`ALLOWED_HOSTS` explicitly rather + than relying on webserver configuration. -.. _virtual host: http://httpd.apache.org/docs/2.2/vhosts/ -.. _ServerName: http://httpd.apache.org/docs/2.2/mod/core.html#servername -.. _ServerAlias: http://httpd.apache.org/docs/2.2/mod/core.html#serveralias +Additionally, as of 1.3.1, Django requires you to explicitly enable support for +the ``X-Forwarded-Host`` header (via the :setting:`USE_X_FORWARDED_HOST` +setting) if your configuration requires it. .. _additional-security-topics: |
