Loading django/conf/global_settings.py +1 −0 Original line number Diff line number Diff line Loading @@ -558,6 +558,7 @@ CSRF_COOKIE_PATH = '/' CSRF_COOKIE_SECURE = False CSRF_COOKIE_HTTPONLY = False CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN' CSRF_TRUSTED_ORIGINS = [] ############ # MESSAGES # Loading django/middleware/csrf.py +9 −4 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ from django.utils.http import same_origin logger = logging.getLogger('django.request') REASON_NO_REFERER = "Referer checking failed - no Referer." REASON_BAD_REFERER = "Referer checking failed - %s does not match %s." REASON_BAD_REFERER = "Referer checking failed - %s does not match any trusted origins." REASON_NO_CSRF_COOKIE = "CSRF cookie not set." REASON_BAD_TOKEN = "CSRF token missing or incorrect." Loading Loading @@ -154,10 +154,15 @@ class CsrfViewMiddleware(object): if referer is None: return self._reject(request, REASON_NO_REFERER) # Here we generate a list of all acceptable HTTP referers, # including the current host since that has been validated # upstream. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) # Note that request.get_host() includes the port. good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) good_hosts.append(request.get_host()) good_referers = ['https://{0}/'.format(host) for host in good_hosts] if not any(same_origin(referer, host) for host in good_referers): reason = REASON_BAD_REFERER % referer return self._reject(request, reason) if csrf_token is None: Loading docs/ref/csrf.txt +3 −1 Original line number Diff line number Diff line Loading @@ -257,7 +257,8 @@ The CSRF protection is based on the following things: due to the fact that HTTP 'Set-Cookie' headers are (unfortunately) accepted by clients that are talking to a site under HTTPS. (Referer checking is not done for HTTP requests because the presence of the Referer header is not reliable enough under HTTP.) reliable enough under HTTP.) Expanding the accepted referers beyond the current host can be done with the :setting:`CSRF_TRUSTED_ORIGINS` setting. This ensures that only forms that have originated from your Web site can be used to POST data back. Loading Loading @@ -460,3 +461,4 @@ A number of settings can be used to control Django's CSRF behavior: * :setting:`CSRF_COOKIE_SECURE` * :setting:`CSRF_FAILURE_VIEW` * :setting:`CSRF_HEADER_NAME` * :setting:`CSRF_TRUSTED_ORIGINS` docs/ref/settings.txt +18 −0 Original line number Diff line number Diff line Loading @@ -428,6 +428,23 @@ any hyphens with underscores, and adding an ``'HTTP_'`` prefix to the name. For example, if your client sends a ``'X-XSRF-TOKEN'`` header, the setting should be ``'HTTP_X_XSRF_TOKEN'``. .. setting:: CSRF_TRUSTED_ORIGINS CSRF_TRUSTED_ORIGINS -------------------- .. versionadded:: 1.9 Default: ``[]`` (Empty list) A list of hosts which are trusted origins for unsafe requests (e.g. ``POST``). For a :meth:`secure <django.http.HttpRequest.is_secure>` unsafe request, Django's CSRF protection requires that the request have a ``Referer`` header that matches the origin present in the ``Host`` header. This prevents, for example, a ``POST`` request from ``subdomain.example.com`` from succeeding against ``api.example.com``. If you need cross-origin unsafe requests over HTTPS, continuing the example, add ``"subdomain.example.com"`` to this list. .. setting:: DATABASES DATABASES Loading Loading @@ -3374,6 +3391,7 @@ Security * :setting:`CSRF_COOKIE_SECURE` * :setting:`CSRF_FAILURE_VIEW` * :setting:`CSRF_HEADER_NAME` * :setting:`CSRF_TRUSTED_ORIGINS` * :setting:`SECRET_KEY` * :setting:`X_FRAME_OPTIONS` Loading docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -484,6 +484,9 @@ CSRF * The request header's name used for CSRF authentication can be customized with :setting:`CSRF_HEADER_NAME`. * The new :setting:`CSRF_TRUSTED_ORIGINS` setting provides a way to allow cross-origin unsafe requests (e.g. ``POST``) over HTTPS. Signals ^^^^^^^ Loading Loading
django/conf/global_settings.py +1 −0 Original line number Diff line number Diff line Loading @@ -558,6 +558,7 @@ CSRF_COOKIE_PATH = '/' CSRF_COOKIE_SECURE = False CSRF_COOKIE_HTTPONLY = False CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN' CSRF_TRUSTED_ORIGINS = [] ############ # MESSAGES # Loading
django/middleware/csrf.py +9 −4 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ from django.utils.http import same_origin logger = logging.getLogger('django.request') REASON_NO_REFERER = "Referer checking failed - no Referer." REASON_BAD_REFERER = "Referer checking failed - %s does not match %s." REASON_BAD_REFERER = "Referer checking failed - %s does not match any trusted origins." REASON_NO_CSRF_COOKIE = "CSRF cookie not set." REASON_BAD_TOKEN = "CSRF token missing or incorrect." Loading Loading @@ -154,10 +154,15 @@ class CsrfViewMiddleware(object): if referer is None: return self._reject(request, REASON_NO_REFERER) # Here we generate a list of all acceptable HTTP referers, # including the current host since that has been validated # upstream. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) # Note that request.get_host() includes the port. good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) good_hosts.append(request.get_host()) good_referers = ['https://{0}/'.format(host) for host in good_hosts] if not any(same_origin(referer, host) for host in good_referers): reason = REASON_BAD_REFERER % referer return self._reject(request, reason) if csrf_token is None: Loading
docs/ref/csrf.txt +3 −1 Original line number Diff line number Diff line Loading @@ -257,7 +257,8 @@ The CSRF protection is based on the following things: due to the fact that HTTP 'Set-Cookie' headers are (unfortunately) accepted by clients that are talking to a site under HTTPS. (Referer checking is not done for HTTP requests because the presence of the Referer header is not reliable enough under HTTP.) reliable enough under HTTP.) Expanding the accepted referers beyond the current host can be done with the :setting:`CSRF_TRUSTED_ORIGINS` setting. This ensures that only forms that have originated from your Web site can be used to POST data back. Loading Loading @@ -460,3 +461,4 @@ A number of settings can be used to control Django's CSRF behavior: * :setting:`CSRF_COOKIE_SECURE` * :setting:`CSRF_FAILURE_VIEW` * :setting:`CSRF_HEADER_NAME` * :setting:`CSRF_TRUSTED_ORIGINS`
docs/ref/settings.txt +18 −0 Original line number Diff line number Diff line Loading @@ -428,6 +428,23 @@ any hyphens with underscores, and adding an ``'HTTP_'`` prefix to the name. For example, if your client sends a ``'X-XSRF-TOKEN'`` header, the setting should be ``'HTTP_X_XSRF_TOKEN'``. .. setting:: CSRF_TRUSTED_ORIGINS CSRF_TRUSTED_ORIGINS -------------------- .. versionadded:: 1.9 Default: ``[]`` (Empty list) A list of hosts which are trusted origins for unsafe requests (e.g. ``POST``). For a :meth:`secure <django.http.HttpRequest.is_secure>` unsafe request, Django's CSRF protection requires that the request have a ``Referer`` header that matches the origin present in the ``Host`` header. This prevents, for example, a ``POST`` request from ``subdomain.example.com`` from succeeding against ``api.example.com``. If you need cross-origin unsafe requests over HTTPS, continuing the example, add ``"subdomain.example.com"`` to this list. .. setting:: DATABASES DATABASES Loading Loading @@ -3374,6 +3391,7 @@ Security * :setting:`CSRF_COOKIE_SECURE` * :setting:`CSRF_FAILURE_VIEW` * :setting:`CSRF_HEADER_NAME` * :setting:`CSRF_TRUSTED_ORIGINS` * :setting:`SECRET_KEY` * :setting:`X_FRAME_OPTIONS` Loading
docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -484,6 +484,9 @@ CSRF * The request header's name used for CSRF authentication can be customized with :setting:`CSRF_HEADER_NAME`. * The new :setting:`CSRF_TRUSTED_ORIGINS` setting provides a way to allow cross-origin unsafe requests (e.g. ``POST``) over HTTPS. Signals ^^^^^^^ Loading