Removed deprecated CsrfResponseMiddleware, and corresponding tests and docs
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15949 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
21ef64e34c
commit
8823021625
|
@ -6,7 +6,6 @@ against request forgeries from other sites.
|
|||
"""
|
||||
|
||||
import hashlib
|
||||
import itertools
|
||||
import re
|
||||
import random
|
||||
|
||||
|
@ -15,14 +14,8 @@ from django.core.urlresolvers import get_callable
|
|||
from django.utils.cache import patch_vary_headers
|
||||
from django.utils.http import same_origin
|
||||
from django.utils.log import getLogger
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.crypto import constant_time_compare
|
||||
|
||||
_POST_FORM_RE = \
|
||||
re.compile(r'(<form\W[^>]*\bmethod\s*=\s*(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
|
||||
|
||||
_HTML_TYPES = ('text/html', 'application/xhtml+xml')
|
||||
|
||||
logger = getLogger('django.request')
|
||||
|
||||
# Use the system (hardware-based) random number generator if it exists.
|
||||
|
@ -49,10 +42,6 @@ def _get_new_csrf_key():
|
|||
return hashlib.md5("%s%s" % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
|
||||
|
||||
|
||||
def _make_legacy_session_token(session_id):
|
||||
return hashlib.md5(settings.SECRET_KEY + session_id).hexdigest()
|
||||
|
||||
|
||||
def get_token(request):
|
||||
"""
|
||||
Returns the the CSRF token required for a POST form. The token is an
|
||||
|
@ -214,83 +203,3 @@ class CsrfViewMiddleware(object):
|
|||
patch_vary_headers(response, ('Cookie',))
|
||||
response.csrf_processing_done = True
|
||||
return response
|
||||
|
||||
|
||||
class CsrfResponseMiddleware(object):
|
||||
"""
|
||||
DEPRECATED
|
||||
Middleware that post-processes a response to add a csrfmiddlewaretoken.
|
||||
|
||||
This exists for backwards compatibility and as an interim measure until
|
||||
applications are converted to using use the csrf_token template tag
|
||||
instead. It will be removed in Django 1.4.
|
||||
"""
|
||||
def __init__(self):
|
||||
import warnings
|
||||
warnings.warn(
|
||||
"CsrfResponseMiddleware and CsrfMiddleware are deprecated; use CsrfViewMiddleware and the template tag instead (see CSRF documentation).",
|
||||
DeprecationWarning
|
||||
)
|
||||
|
||||
def process_response(self, request, response):
|
||||
if getattr(response, 'csrf_exempt', False):
|
||||
return response
|
||||
|
||||
if response['Content-Type'].split(';')[0] in _HTML_TYPES:
|
||||
csrf_token = get_token(request)
|
||||
# If csrf_token is None, we have no token for this request, which probably
|
||||
# means that this is a response from a request middleware.
|
||||
if csrf_token is None:
|
||||
return response
|
||||
|
||||
# ensure we don't add the 'id' attribute twice (HTML validity)
|
||||
idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
|
||||
itertools.repeat(''))
|
||||
def add_csrf_field(match):
|
||||
"""Returns the matched <form> tag plus the added <input> element"""
|
||||
return mark_safe(match.group() + "<div style='display:none;'>" + \
|
||||
"<input type='hidden' " + idattributes.next() + \
|
||||
" name='csrfmiddlewaretoken' value='" + csrf_token + \
|
||||
"' /></div>")
|
||||
|
||||
# Modify any POST forms
|
||||
response.content, n = _POST_FORM_RE.subn(add_csrf_field, response.content)
|
||||
if n > 0:
|
||||
# Content varies with the CSRF cookie, so set the Vary header.
|
||||
patch_vary_headers(response, ('Cookie',))
|
||||
|
||||
# Since the content has been modified, any Etag will now be
|
||||
# incorrect. We could recalculate, but only if we assume that
|
||||
# the Etag was set by CommonMiddleware. The safest thing is just
|
||||
# to delete. See bug #9163
|
||||
del response['ETag']
|
||||
return response
|
||||
|
||||
|
||||
class CsrfMiddleware(object):
|
||||
"""
|
||||
Django middleware that adds protection against Cross Site
|
||||
Request Forgeries by adding hidden form fields to POST forms and
|
||||
checking requests for the correct value.
|
||||
|
||||
CsrfMiddleware uses two middleware, CsrfViewMiddleware and
|
||||
CsrfResponseMiddleware, which can be used independently. It is recommended
|
||||
to use only CsrfViewMiddleware and use the csrf_token template tag in
|
||||
templates for inserting the token.
|
||||
"""
|
||||
# We can't just inherit from CsrfViewMiddleware and CsrfResponseMiddleware
|
||||
# because both have process_response methods.
|
||||
def __init__(self):
|
||||
self.response_middleware = CsrfResponseMiddleware()
|
||||
self.view_middleware = CsrfViewMiddleware()
|
||||
|
||||
def process_response(self, request, resp):
|
||||
# We must do the response post-processing first, because that calls
|
||||
# get_token(), which triggers a flag saying that the CSRF cookie needs
|
||||
# to be sent (done in CsrfViewMiddleware.process_response)
|
||||
resp2 = self.response_middleware.process_response(request, resp)
|
||||
return self.view_middleware.process_response(request, resp2)
|
||||
|
||||
def process_view(self, request, callback, callback_args, callback_kwargs):
|
||||
return self.view_middleware.process_view(request, callback, callback_args,
|
||||
callback_kwargs)
|
||||
|
|
|
@ -17,28 +17,18 @@ The first defense against CSRF attacks is to ensure that GET requests are
|
|||
side-effect free. POST requests can then be protected by following the steps
|
||||
below.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
The 'contrib' apps, including the admin, use the functionality described
|
||||
here. Because it is security related, a few things have been added to core
|
||||
functionality to allow this to happen without any required upgrade steps.
|
||||
|
||||
.. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF
|
||||
|
||||
How to use it
|
||||
=============
|
||||
|
||||
.. versionchanged:: 1.2
|
||||
The template tag functionality (the recommended way to use this) was added
|
||||
in version 1.2. The previous method (still available) is described under
|
||||
`Legacy method`_.
|
||||
|
||||
To enable CSRF protection for your views, follow these steps:
|
||||
|
||||
1. Add the middleware
|
||||
``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of
|
||||
middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come
|
||||
before ``CsrfResponseMiddleware`` if that is being used, and before any
|
||||
view middleware that assume that CSRF attacks have been dealt with.)
|
||||
and before any view middleware that assume that CSRF attacks have
|
||||
been dealt with.)
|
||||
|
||||
Alternatively, you can use the decorator
|
||||
``django.views.decorators.csrf.csrf_protect`` on particular views you
|
||||
|
@ -47,7 +37,7 @@ To enable CSRF protection for your views, follow these steps:
|
|||
2. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside
|
||||
the ``<form>`` element if the form is for an internal URL, e.g.::
|
||||
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<form action="." method="post">{% csrf_token %}
|
||||
|
||||
This should not be done for POST forms that target external URLs, since
|
||||
that would cause the CSRF token to be leaked, leading to a vulnerability.
|
||||
|
@ -78,8 +68,8 @@ To enable CSRF protection for your views, follow these steps:
|
|||
takes care of this step for you.
|
||||
|
||||
The utility script ``extras/csrf_migration_helper.py`` can help to automate the
|
||||
finding of code and templates that may need to be upgraded. It contains full
|
||||
help on how to use it.
|
||||
finding of code and templates that may need these steps. It contains full help
|
||||
on how to use it.
|
||||
|
||||
.. _csrf-ajax:
|
||||
|
||||
|
@ -146,145 +136,9 @@ Use of the decorator is **not recommended** by itself, since if you forget to
|
|||
use it, you will have a security hole. The 'belt and braces' strategy of using
|
||||
both is fine, and will incur minimal overhead.
|
||||
|
||||
Legacy method
|
||||
-------------
|
||||
|
||||
In Django 1.1, the template tag did not exist. Instead, a post-processing
|
||||
middleware that re-wrote POST forms to include the CSRF token was used. If you
|
||||
are upgrading a site from version 1.1 or earlier, please read this section and
|
||||
the `Upgrading notes`_ below. The post-processing middleware is still available
|
||||
as ``CsrfResponseMiddleware``, and it can be used by following these steps:
|
||||
|
||||
1. Follow step 1 above to install ``CsrfViewMiddleware``.
|
||||
|
||||
2. Add ``'django.middleware.csrf.CsrfResponseMiddleware'`` to your
|
||||
:setting:`MIDDLEWARE_CLASSES` setting.
|
||||
|
||||
``CsrfResponseMiddleware`` needs to process the response before things
|
||||
like compression or setting ofETags happen to the response, so it must
|
||||
come after ``GZipMiddleware``, ``CommonMiddleware`` and
|
||||
``ConditionalGetMiddleware`` in the list. It also must come after
|
||||
``CsrfViewMiddleware``.
|
||||
|
||||
Use of the ``CsrfResponseMiddleware`` is not recommended because of the
|
||||
performance hit it imposes, and because of a potential security problem (see
|
||||
below). It can be used as an interim measure until applications have been
|
||||
updated to use the :ttag:`csrf_token` tag. It is deprecated and will be
|
||||
removed in Django 1.4.
|
||||
|
||||
Django 1.1 and earlier provided a single ``CsrfMiddleware`` class. This is also
|
||||
still available for backwards compatibility. It combines the functions of the
|
||||
two middleware.
|
||||
|
||||
Note also that previous versions of these classes depended on the sessions
|
||||
framework, but this dependency has now been removed, with backward compatibility
|
||||
support so that upgrading will not produce any issues.
|
||||
|
||||
Security of legacy method
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The post-processing ``CsrfResponseMiddleware`` adds the CSRF token to all POST
|
||||
forms (unless the view has been decorated with ``csrf_response_exempt``). If
|
||||
the POST form has an external untrusted site as its target, rather than an
|
||||
internal page, that site will be sent the CSRF token when the form is submitted.
|
||||
Armed with this leaked information, that site will then be able to successfully
|
||||
launch a CSRF attack on your site against that user. The
|
||||
``@csrf_response_exempt`` decorator can be used to fix this, but only if the
|
||||
page doesn't also contain internal forms that require the token.
|
||||
|
||||
.. _ref-csrf-upgrading-notes:
|
||||
|
||||
Upgrading notes
|
||||
---------------
|
||||
|
||||
When upgrading to version 1.2 or later, you may have applications that rely on
|
||||
the old post-processing functionality for CSRF protection, or you may not have
|
||||
enabled any CSRF protection. This section outlines the steps necessary for a
|
||||
smooth upgrade, without having to fix all the applications to use the new
|
||||
template tag method immediately.
|
||||
|
||||
First of all, the location of the middleware and related functions have
|
||||
changed. There are backwards compatible stub files so that old imports will
|
||||
continue to work for now, but they are deprecated and will be removed in Django
|
||||
1.4. The following changes have been made:
|
||||
|
||||
* Middleware have been moved to ``django.middleware.csrf``
|
||||
* Decorators have been moved to ``django.views.decorators.csrf``
|
||||
|
||||
====================================================== ==============================================
|
||||
Old New
|
||||
====================================================== ==============================================
|
||||
django.contrib.csrf.middleware.CsrfMiddleware django.middleware.csrf.CsrfMiddleware
|
||||
django.contrib.csrf.middleware.CsrfViewMiddleware django.middleware.csrf.CsrfViewMiddleware
|
||||
django.contrib.csrf.middleware.CsrfResponseMiddleware django.middleware.csrf.CsrfResponseMiddleware
|
||||
django.contrib.csrf.middleware.csrf_exempt django.views.decorators.csrf.csrf_exempt
|
||||
django.contrib.csrf.middleware.csrf_view_exempt django.views.decorators.csrf.csrf_view_exempt
|
||||
django.contrib.csrf.middleware.csrf_response_exempt django.views.decorators.csrf.csrf_response_exempt
|
||||
====================================================== ==============================================
|
||||
|
||||
You should update any imports, and also the paths in your
|
||||
:setting:`MIDDLEWARE_CLASSES`.
|
||||
|
||||
If you have ``CsrfMiddleware`` in your :setting:`MIDDLEWARE_CLASSES`, you will now
|
||||
have a working installation with CSRF protection. It is recommended at this
|
||||
point that you replace ``CsrfMiddleware`` with its two components,
|
||||
``CsrfViewMiddleware`` and ``CsrfResponseMiddleware`` (in that order).
|
||||
|
||||
If you do not have any of the middleware in your :setting:`MIDDLEWARE_CLASSES`,
|
||||
you will have a working installation but without any CSRF protection for your
|
||||
views (just as you had before). It is strongly recommended to install
|
||||
``CsrfViewMiddleware`` and ``CsrfResponseMiddleware``, as described above.
|
||||
|
||||
Note that contrib apps, such as the admin, have been updated to use the
|
||||
``csrf_protect`` decorator, so that they are secured even if you do not add the
|
||||
``CsrfViewMiddleware`` to your settings. However, if you have supplied
|
||||
customised templates to any of the view functions of contrib apps (whether
|
||||
explicitly via a keyword argument, or by overriding built-in templates), **you
|
||||
MUST update them** to include the :ttag:`csrf_token` template tag as described
|
||||
above, or they will stop working. (If you cannot update these templates for
|
||||
some reason, you will be forced to use ``CsrfResponseMiddleware`` for these
|
||||
views to continue working).
|
||||
|
||||
Note also, if you are using the comments app, and you are not going to add
|
||||
``CsrfViewMiddleware`` to your settings (not recommended), you will need to add
|
||||
the ``csrf_protect`` decorator to any views that include the comment forms and
|
||||
target the comment views (usually using the :ttag:`comment_form_target` template
|
||||
tag).
|
||||
|
||||
Assuming you have followed the above, all views in your Django site will now be
|
||||
protected by the ``CsrfViewMiddleware``. Contrib apps meet the requirements
|
||||
imposed by the ``CsrfViewMiddleware`` using the template tag, and other
|
||||
applications in your project will meet its requirements by virtue of the
|
||||
``CsrfResponseMiddleware``.
|
||||
|
||||
The next step is to update all your applications to use the template tag, as
|
||||
described in `How to use it`_, steps 2-3. This can be done as soon as is
|
||||
practical. Any applications that are updated will now require Django 1.1.2 or
|
||||
later, since they will use the CSRF template tag which was not available in
|
||||
earlier versions. (The template tag in 1.1.2 is actually a no-op that exists
|
||||
solely to ease the transition to 1.2 — it allows apps to be created that have
|
||||
CSRF protection under 1.2 without requiring users of the apps to upgrade to the
|
||||
Django 1.2.X series).
|
||||
|
||||
The utility script ``extras/csrf_migration_helper.py`` can help to automate the
|
||||
finding of code and templates that may need to be upgraded. It contains full
|
||||
help on how to use it.
|
||||
|
||||
Finally, once all applications are upgraded, ``CsrfResponseMiddleware`` can be
|
||||
removed from your settings.
|
||||
|
||||
While ``CsrfResponseMiddleware`` is still in use, the ``csrf_response_exempt``
|
||||
decorator, described in `Exceptions`_, may be useful. The post-processing
|
||||
middleware imposes a performance hit and a potential vulnerability, and any
|
||||
views that have been upgraded to use the new template tag method no longer need
|
||||
it.
|
||||
|
||||
Exceptions
|
||||
----------
|
||||
|
||||
.. versionchanged:: 1.2
|
||||
Import paths for the decorators below were changed.
|
||||
|
||||
To manually exclude a view function from being handled by either of the two CSRF
|
||||
middleware, you can use the ``csrf_exempt`` decorator, found in the
|
||||
``django.views.decorators.csrf`` module. For example::
|
||||
|
@ -295,13 +149,6 @@ middleware, you can use the ``csrf_exempt`` decorator, found in the
|
|||
def my_view(request):
|
||||
return HttpResponse('Hello world')
|
||||
|
||||
Like the middleware, the ``csrf_exempt`` decorator is composed of two parts: a
|
||||
``csrf_view_exempt`` decorator and a ``csrf_response_exempt`` decorator, found
|
||||
in the same module. These disable the view protection mechanism
|
||||
(``CsrfViewMiddleware``) and the response post-processing
|
||||
(``CsrfResponseMiddleware``) respectively. They can be used individually if
|
||||
required.
|
||||
|
||||
Subdomains
|
||||
----------
|
||||
|
||||
|
@ -350,8 +197,7 @@ The CSRF protection is based on the following things:
|
|||
outgoing POST forms. The value of this field is the value of the CSRF
|
||||
cookie.
|
||||
|
||||
This part is done by the template tag (and with the legacy method, it is done
|
||||
by ``CsrfResponseMiddleware``).
|
||||
This part is done by the template tag.
|
||||
|
||||
3. For all incoming POST requests, a CSRF cookie must be present, and the
|
||||
'csrfmiddlewaretoken' field must be present and correct. If it isn't, the
|
||||
|
@ -375,22 +221,16 @@ forms). GET requests ought never to have any potentially dangerous side effects
|
|||
(see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a CSRF attack with a GET
|
||||
request ought to be harmless.
|
||||
|
||||
``CsrfResponseMiddleware`` checks the Content-Type before modifying the
|
||||
response, and only pages that are served as 'text/html' or
|
||||
'application/xml+xhtml' are modified.
|
||||
|
||||
.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
|
||||
|
||||
Caching
|
||||
=======
|
||||
|
||||
If the :ttag:`csrf_token` template tag is used by a template (or the ``get_token``
|
||||
function is called some other way), ``CsrfViewMiddleware`` will add a cookie and
|
||||
a ``Vary: Cookie`` header to the response. Similarly,
|
||||
``CsrfResponseMiddleware`` will send the ``Vary: Cookie`` header if it inserted
|
||||
a token. This means that these middleware will play well with the cache
|
||||
middleware if it is used as instructed (``UpdateCacheMiddleware`` goes before
|
||||
all other middleware).
|
||||
If the :ttag:`csrf_token` template tag is used by a template (or the
|
||||
``get_token`` function is called some other way), ``CsrfViewMiddleware`` will
|
||||
add a cookie and a ``Vary: Cookie`` header to the response. This means that the
|
||||
middleware will play well with the cache middleware if it is used as instructed
|
||||
(``UpdateCacheMiddleware`` goes before all other middleware).
|
||||
|
||||
However, if you use cache decorators on individual views, the CSRF middleware
|
||||
will not yet have been able to set the Vary header. In this case, on any views
|
||||
|
@ -434,13 +274,6 @@ to set cookies). Note that even without CSRF, there are other vulnerabilities,
|
|||
such as session fixation, that make giving subdomains to untrusted parties a bad
|
||||
idea, and these vulnerabilities cannot easily be fixed with current browsers.
|
||||
|
||||
If you are using ``CsrfResponseMiddleware`` and your app creates HTML pages and
|
||||
forms in some unusual way, (e.g. it sends fragments of HTML in JavaScript
|
||||
document.write statements) you might bypass the filter that adds the hidden
|
||||
field to the form, in which case form submission will always fail. You should
|
||||
use the template tag or :meth:`django.middleware.csrf.get_token` to get
|
||||
the CSRF token and ensure it is included when your form is submitted.
|
||||
|
||||
Contrib and reusable apps
|
||||
=========================
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import warnings
|
|||
|
||||
from django.test import TestCase
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.middleware.csrf import CsrfMiddleware, CsrfViewMiddleware
|
||||
from django.middleware.csrf import CsrfViewMiddleware
|
||||
from django.views.decorators.csrf import csrf_exempt, csrf_view_exempt, requires_csrf_token
|
||||
from django.core.context_processors import csrf
|
||||
from django.conf import settings
|
||||
|
@ -16,11 +16,6 @@ def post_form_response():
|
|||
""", mimetype="text/html")
|
||||
return resp
|
||||
|
||||
def post_form_response_non_html():
|
||||
resp = post_form_response()
|
||||
resp["Content-Type"] = "application/xml"
|
||||
return resp
|
||||
|
||||
def post_form_view(request):
|
||||
"""A view that returns a POST form (without a token)"""
|
||||
return post_form_response()
|
||||
|
@ -54,7 +49,7 @@ class TestingHttpRequest(HttpRequest):
|
|||
def is_secure(self):
|
||||
return getattr(self, '_is_secure', False)
|
||||
|
||||
class CsrfMiddlewareTest(TestCase):
|
||||
class CsrfViewMiddlewareTest(TestCase):
|
||||
# The csrf token is potentially from an untrusted source, so could have
|
||||
# characters that need dealing with.
|
||||
_csrf_id_cookie = "<1>\xc2\xa1"
|
||||
|
@ -94,51 +89,12 @@ class CsrfMiddlewareTest(TestCase):
|
|||
def _check_token_present(self, response, csrf_id=None):
|
||||
self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id))
|
||||
|
||||
# Check the post processing and outgoing cookie
|
||||
def test_process_response_no_csrf_cookie(self):
|
||||
def test_process_response_get_token_used(self):
|
||||
"""
|
||||
When no prior CSRF cookie exists, check that the cookie is created and a
|
||||
token is inserted.
|
||||
When get_token is used, check that the cookie is created and headers
|
||||
patched.
|
||||
"""
|
||||
req = self._get_GET_no_csrf_cookie_request()
|
||||
CsrfMiddleware().process_view(req, post_form_view, (), {})
|
||||
|
||||
resp = post_form_response()
|
||||
resp_content = resp.content # needed because process_response modifies resp
|
||||
resp2 = CsrfMiddleware().process_response(req, resp)
|
||||
|
||||
csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
|
||||
self.assertNotEqual(csrf_cookie, False)
|
||||
self.assertNotEqual(resp_content, resp2.content)
|
||||
self._check_token_present(resp2, csrf_cookie.value)
|
||||
# Check the Vary header got patched correctly
|
||||
self.assertTrue('Cookie' in resp2.get('Vary',''))
|
||||
|
||||
def test_process_response_for_exempt_view(self):
|
||||
"""
|
||||
Check that a view decorated with 'csrf_view_exempt' is still
|
||||
post-processed to add the CSRF token.
|
||||
"""
|
||||
req = self._get_GET_no_csrf_cookie_request()
|
||||
CsrfMiddleware().process_view(req, csrf_view_exempt(post_form_view), (), {})
|
||||
|
||||
resp = post_form_response()
|
||||
resp_content = resp.content # needed because process_response modifies resp
|
||||
resp2 = CsrfMiddleware().process_response(req, resp)
|
||||
|
||||
csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
|
||||
self.assertNotEqual(csrf_cookie, False)
|
||||
self.assertNotEqual(resp_content, resp2.content)
|
||||
self._check_token_present(resp2, csrf_cookie.value)
|
||||
|
||||
def test_process_response_no_csrf_cookie_view_only_get_token_used(self):
|
||||
"""
|
||||
When no prior CSRF cookie exists, check that the cookie is created, even
|
||||
if only CsrfViewMiddleware is used.
|
||||
"""
|
||||
# This is checking that CsrfViewMiddleware has the cookie setting
|
||||
# code. Most of the other tests use CsrfMiddleware.
|
||||
req = self._get_GET_no_csrf_cookie_request()
|
||||
# token_view calls get_token() indirectly
|
||||
CsrfViewMiddleware().process_view(req, token_view, (), {})
|
||||
resp = token_view(req)
|
||||
|
@ -146,6 +102,7 @@ class CsrfMiddlewareTest(TestCase):
|
|||
|
||||
csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
|
||||
self.assertNotEqual(csrf_cookie, False)
|
||||
self.assertTrue('Cookie' in resp2.get('Vary',''))
|
||||
|
||||
def test_process_response_get_token_not_used(self):
|
||||
"""
|
||||
|
@ -167,43 +124,6 @@ class CsrfMiddlewareTest(TestCase):
|
|||
csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
|
||||
self.assertEqual(csrf_cookie, False)
|
||||
|
||||
def test_process_response_existing_csrf_cookie(self):
|
||||
"""
|
||||
Check that the token is inserted when a prior CSRF cookie exists
|
||||
"""
|
||||
req = self._get_GET_csrf_cookie_request()
|
||||
CsrfMiddleware().process_view(req, post_form_view, (), {})
|
||||
|
||||
resp = post_form_response()
|
||||
resp_content = resp.content # needed because process_response modifies resp
|
||||
resp2 = CsrfMiddleware().process_response(req, resp)
|
||||
self.assertNotEqual(resp_content, resp2.content)
|
||||
self._check_token_present(resp2)
|
||||
|
||||
def test_process_response_non_html(self):
|
||||
"""
|
||||
Check the the post-processor does nothing for content-types not in _HTML_TYPES.
|
||||
"""
|
||||
req = self._get_GET_no_csrf_cookie_request()
|
||||
CsrfMiddleware().process_view(req, post_form_view, (), {})
|
||||
resp = post_form_response_non_html()
|
||||
resp_content = resp.content # needed because process_response modifies resp
|
||||
resp2 = CsrfMiddleware().process_response(req, resp)
|
||||
self.assertEqual(resp_content, resp2.content)
|
||||
|
||||
def test_process_response_exempt_view(self):
|
||||
"""
|
||||
Check that no post processing is done for an exempt view
|
||||
"""
|
||||
req = self._get_GET_csrf_cookie_request()
|
||||
view = csrf_exempt(post_form_view)
|
||||
CsrfMiddleware().process_view(req, view, (), {})
|
||||
|
||||
resp = view(req)
|
||||
resp_content = resp.content
|
||||
resp2 = CsrfMiddleware().process_response(req, resp)
|
||||
self.assertEqual(resp_content, resp2.content)
|
||||
|
||||
# Check the request processing
|
||||
def test_process_request_no_csrf_cookie(self):
|
||||
"""
|
||||
|
@ -211,7 +131,7 @@ class CsrfMiddlewareTest(TestCase):
|
|||
incoming request. This will stop login CSRF.
|
||||
"""
|
||||
req = self._get_POST_no_csrf_cookie_request()
|
||||
req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
|
||||
req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
||||
self.assertEqual(403, req2.status_code)
|
||||
|
||||
def test_process_request_csrf_cookie_no_token(self):
|
||||
|
@ -220,7 +140,7 @@ class CsrfMiddlewareTest(TestCase):
|
|||
rejects the incoming request.
|
||||
"""
|
||||
req = self._get_POST_csrf_cookie_request()
|
||||
req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
|
||||
req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
||||
self.assertEqual(403, req2.status_code)
|
||||
|
||||
def test_process_request_csrf_cookie_and_token(self):
|
||||
|
@ -228,7 +148,7 @@ class CsrfMiddlewareTest(TestCase):
|
|||
Check that if both a cookie and a token is present, the middleware lets it through.
|
||||
"""
|
||||
req = self._get_POST_request_with_token()
|
||||
req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
|
||||
req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
||||
self.assertEqual(None, req2)
|
||||
|
||||
def test_process_request_csrf_cookie_no_token_exempt_view(self):
|
||||
|
@ -237,7 +157,7 @@ class CsrfMiddlewareTest(TestCase):
|
|||
decorator has been applied to the view, the middleware lets it through
|
||||
"""
|
||||
req = self._get_POST_csrf_cookie_request()
|
||||
req2 = CsrfMiddleware().process_view(req, csrf_exempt(post_form_view), (), {})
|
||||
req2 = CsrfViewMiddleware().process_view(req, csrf_exempt(post_form_view), (), {})
|
||||
self.assertEqual(None, req2)
|
||||
|
||||
def test_csrf_token_in_header(self):
|
||||
|
@ -246,7 +166,7 @@ class CsrfMiddlewareTest(TestCase):
|
|||
"""
|
||||
req = self._get_POST_csrf_cookie_request()
|
||||
req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id
|
||||
req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
|
||||
req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
||||
self.assertEqual(None, req2)
|
||||
|
||||
# Tests for the template tag method
|
||||
|
@ -307,15 +227,6 @@ class CsrfMiddlewareTest(TestCase):
|
|||
csrf_cookie = resp2.cookies[settings.CSRF_COOKIE_NAME]
|
||||
self._check_token_present(resp, csrf_id=csrf_cookie.value)
|
||||
|
||||
def test_response_middleware_without_view_middleware(self):
|
||||
"""
|
||||
Check that CsrfResponseMiddleware finishes without error if the view middleware
|
||||
has not been called, as is the case if a request middleware returns a response.
|
||||
"""
|
||||
req = self._get_GET_no_csrf_cookie_request()
|
||||
resp = post_form_view(req)
|
||||
CsrfMiddleware().process_response(req, resp)
|
||||
|
||||
def test_https_bad_referer(self):
|
||||
"""
|
||||
Test that a POST HTTPS request with a bad referer is rejected
|
||||
|
|
Loading…
Reference in New Issue