1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.

This is a large change to CSRF protection for Django.  It includes:

 * removing the dependency on the session framework.
 * deprecating CsrfResponseMiddleware, and replacing with a core template tag.
 * turning on CSRF protection by default by adding CsrfViewMiddleware to
   the default value of MIDDLEWARE_CLASSES.
 * protecting all contrib apps (whatever is in settings.py)
   using a decorator.

For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.

Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.

Details of the rationale for these changes is found here:

http://code.djangoproject.com/wiki/CsrfProtection

As of this commit, the CSRF code is mainly in 'contrib'.  The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.



git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Luke Plant
2009-10-26 23:23:07 +00:00
parent d1da261417
commit 8e70cef9b6
47 changed files with 1439 additions and 246 deletions

View File

@@ -13,6 +13,12 @@ their deprecation, as per the :ref:`Django deprecation policy
hooking up admin URLs. This has been deprecated since the 1.1
release.
* 1.4
* ``CsrfResponseMiddleware``. This has been deprecated since the 1.2
release, in favour of the template tag method for inserting the CSRF
token. ``CsrfMiddleware``, which combines ``CsrfResponseMiddleware``
and ``CsrfViewMiddleware``, is also deprecated.
* 2.0
* ``django.views.defaults.shortcut()``. This function has been moved
to ``django.contrib.contenttypes.views.shortcut()`` as part of the

View File

@@ -21,6 +21,7 @@ tutorial, so that the template contains an HTML ``<form>`` element:
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="/polls/{{ poll.id }}/vote/" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
@@ -46,6 +47,28 @@ A quick rundown:
* ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone
through its loop
* Since we are creating a POST form (which can have the effect of modifying
data), we unfortunately need to worry about Cross Site Request Forgeries.
Thankfully, you don't have to worry too hard, because Django comes with
very easy-to-use system for protecting against it. In short, all POST
forms that are targetted at internal URLs need the ``{% csrf_token %}``
template tag adding.
The ``{% csrf_token %}`` tag requires information from the request object, which
is not normally accessible from within the template context. To fix this, a
small adjustment needs to be made to the ``detail`` view, so that it looks like
the following::
from django.template import RequestContext
# ...
def detail(request, poll_id):
p = get_object_or_404(Poll, pk=poll_id)
return render_to_response('polls/detail.html', {'poll': p},
context_instance=RequestContext(request))
The details of how this works are explained in the documentation for
:ref:`RequestContext <subclassing-context-requestcontext>`.
Now, let's create a Django view that handles the submitted data and does
something with it. Remember, in :ref:`Tutorial 3 <intro-tutorial03>`, we
created a URLconf for the polls application that includes this line::
@@ -58,6 +81,7 @@ create a real version. Add the following to ``mysite/polls/views.py``::
from django.shortcuts import get_object_or_404, render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.template import RequestContext
from mysite.polls.models import Choice, Poll
# ...
def vote(request, poll_id):
@@ -69,7 +93,7 @@ create a real version. Add the following to ``mysite/polls/views.py``::
return render_to_response('polls/detail.html', {
'poll': p,
'error_message': "You didn't select a choice.",
})
}, context_instance=RequestContext(request))
else:
selected_choice.votes += 1
selected_choice.save()

View File

@@ -7,46 +7,186 @@ Cross Site Request Forgery protection
.. module:: django.contrib.csrf
:synopsis: Protects against Cross Site Request Forgeries
The CsrfMiddleware class provides easy-to-use protection against
The CSRF middleware and template tag provides easy-to-use protection against
`Cross Site Request Forgeries`_. This type of attack occurs when a malicious
Web site creates a link or form button that is intended to perform some action
on your Web site, using the credentials of a logged-in user who is tricked
into clicking on the link in their browser.
Web site contains a link, a form button or some javascript that is intended to
perform some action on your Web site, using the credentials of a logged-in user
who visits the malicious site in their browser. A related type of attack,
'login CSRF', where an attacking site tricks a user's browser into logging into
a site with someone else's credentials, is also covered.
The first defense against CSRF attacks is to ensure that GET requests
are side-effect free. POST requests can then be protected by adding this
middleware into your list of installed middleware.
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
=============
Add the middleware ``'django.contrib.csrf.middleware.CsrfMiddleware'`` to your
list of middleware classes, :setting:`MIDDLEWARE_CLASSES`. It needs to process
the response after the SessionMiddleware, so must come before it in the list. It
also must process the response before things like compression or setting of
ETags happen to the response, so it must come after GZipMiddleware,
CommonMiddleware and ConditionalGetMiddleware in the list.
.. 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`_.
The ``CsrfMiddleware`` class is actually composed of two middleware:
``CsrfViewMiddleware`` which performs the checks on incoming requests,
and ``CsrfResponseMiddleware`` which performs post-processing of the
result. This allows the individual components to be used and/or
replaced instead of using ``CsrfMiddleware``.
To enable CSRF protection for your views, follow these steps:
.. versionchanged:: 1.1
(previous versions of Django did not provide these two components
of ``CsrfMiddleware`` as described above)
1. Add the middleware
``'django.contrib.csrf.middleware.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.)
Alternatively, you can use the decorator
``django.contrib.csrf.decorators.csrf_protect`` on particular views you
want to protect. This 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.
2. In any template that uses a POST form, use the ``csrf_token`` tag inside
the ``<form>`` element if the form is for an internal URL, e.g.::
<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.
3. In the corresponding view functions, ensure that the
``'django.contrib.csrf.context_processors.csrf'`` context processor is
being used. Usually, this can be done in one of two ways:
1. Use RequestContext, which always uses
``'django.contrib.csrf.context_processors.csrf'`` (no matter what your
TEMPLATE_CONTEXT_PROCESSORS setting). If you are using
generic views or contrib apps, you are covered already, since these
apps use RequestContext throughout.
2. Manually import and use the processor to generate the CSRF token and
add it to the template context. e.g.::
from django.contrib.csrf.context_processors import csrf
from django.shortcuts import render_to_response
def my_view(request):
c = {}
c.update(csrf(request))
# ... view code here
return render_to_response("a_template.html", c)
You may want to write your own ``render_to_response`` wrapper that
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.
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 CRSF 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.contrib.csrf.middleware.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 ``{% crsf_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.
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.
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).
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.2 or
later, since they will use the CSRF template tag which was not available in
earlier versions.
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
----------
.. versionadded:: 1.1
To manually exclude a view function from being handled by the
CsrfMiddleware, you can use the ``csrf_exempt`` decorator, found in
the ``django.contrib.csrf.middleware`` module. For example::
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.contrib.csrf.middleware`` module. For example::
from django.contrib.csrf.middleware import csrf_exempt
@@ -54,71 +194,172 @@ the ``django.contrib.csrf.middleware`` module. For example::
return HttpResponse('Hello world')
my_view = csrf_exempt(my_view)
Like the middleware itself, 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.
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.
You don't have to worry about doing this for most AJAX views. Any
request sent with "X-Requested-With: XMLHttpRequest" is automatically
exempt. (See the next section.)
You don't have to worry about doing this for most AJAX views. Any request sent
with "X-Requested-With: XMLHttpRequest" is automatically exempt. (See the `How
it works`_ section.)
Subdomains
----------
By default, CSRF cookies are specific to the subdomain they are set for. This
means that a form served from one subdomain (e.g. server1.example.com) will not
be able to have a target on another subdomain (e.g. server2.example.com). This
restriction can be removed by setting :setting:`CSRF_COOKIE_DOMAIN` to be
something like ``".example.com"``.
Please note that, with or without use of this setting, this CSRF protection
mechanism is not safe against cross-subdomain attacks -- see `Limitations`_.
Rejected requests
=================
By default, a '403 Forbidden' response is sent to the user if an incoming
request fails the checks performed by ``CsrfViewMiddleware``. This should
usually only be seen when there is a genuine Cross Site Request Forgery, or
when, due to a programming error, the CSRF token has not been included with a
POST form.
No logging is done, and the error message is not very friendly, so you may want
to provide your own page for handling this condition. To do this, simply set
the :setting:`CSRF_FAILURE_VIEW` setting to a dotted path to your own view
function, which should have the following signature::
def csrf_failure(request, reason="")
where ``reason`` is a short message (intended for developers or logging, not for
end users) indicating the reason the request was rejected.
How it works
============
CsrfMiddleware does two things:
The CSRF protection is based on the following things:
1. It modifies outgoing requests by adding a hidden form field to all
'POST' forms, with the name 'csrfmiddlewaretoken' and a value which is
a hash of the session ID plus a secret. If there is no session ID set,
this modification of the response isn't done, so there is very little
performance penalty for those requests that don't have a session.
(This is done by ``CsrfResponseMiddleware``).
1. A CSRF cookie that is set to a random value (a session independent nonce, as
it is called), which other sites will not have access to.
2. On all incoming POST requests that have the session cookie set, it
checks that the 'csrfmiddlewaretoken' is present and correct. If it
isn't, the user will get a 403 error. (This is done by
``CsrfViewMiddleware``)
This cookie is set by ``CsrfViewMiddleware``. It is meant to be permanent,
but since there is no way to set a cookie that never expires, it is sent with
every response that has called ``django.contrib.csrf.middleware.get_token()``
(the function used internally to retrieve the CSRF token).
This ensures that only forms that have originated from your Web site
can be used to POST data back.
2. A hidden form field with the name 'csrfmiddlewaretoken' present in all
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``).
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
user will get a 403 error.
This check is done by ``CsrfViewMiddleware``.
4. In addition, for HTTPS requests, strict referer checking is done by
``CsrfViewMiddleware``. This is necessary to address a Man-In-The-Middle
attack that is possible under HTTPS when using a session independent nonce,
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.)
This ensures that only forms that have originated from your Web site can be used
to POST data back.
It deliberately only targets HTTP POST requests (and the corresponding POST
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.
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.
POST requests that are not accompanied by a session cookie are not protected,
but they do not need to be protected, since the 'attacking' Web site
could make these kind of requests anyway.
``CsrfResponseMiddleware`` checks the Content-Type before modifying the
response, and only pages that are served as 'text/html' or
'application/xml+xhtml' are modified.
The Content-Type is checked before modifying the response, and only
pages that are served as 'text/html' or 'application/xml+xhtml'
are modified.
AJAX
----
The middleware tries to be smart about requests that come in via AJAX. Many
JavaScript toolkits send an "X-Requested-With: XMLHttpRequest" HTTP header;
these requests are detected and automatically *not* handled by this middleware.
We can do this safely because, in the context of a browser, the header can only
be added by using ``XMLHttpRequest``, and browsers already implement a
same-domain policy for ``XMLHttpRequest``. (Note that this is not secure if you
don't trust content within the same domain or subdomains.)
The middleware tries to be smart about requests that come in via AJAX. Most
modern JavaScript toolkits send an "X-Requested-With: XMLHttpRequest" HTTP
header; these requests are detected and automatically *not* handled by this
middleware. We can do this safely because, in the context of a browser, the
header can only be added by using ``XMLHttpRequest``, and browsers already
implement a same-domain policy for ``XMLHttpRequest``.
For the more recent browsers that relax this same-domain policy, custom headers
like "X-Requested-With" are only allowed after the browser has done a
'preflight' check to the server to see if the cross-domain request is allowed,
using a strictly 'opt in' mechanism, so the exception for AJAX is still safe—if
the developer has specifically opted in to allowing cross-site AJAX POST
requests on a specific URL, they obviously don't want the middleware to disallow
exactly that.
.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Caching
=======
If the ``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).
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
that will require a CSRF token to be inserted you should use the
:func:`django.views.decorators.vary.vary_on_cookie` decorator first::
from django.views.decorators.cache import cache_page
from django.views.decorators.vary import vary_on_cookie
@cache_page(60 * 15)
@vary_on_cookie
def my_view(request):
# ...
Testing
=======
The ``CsrfViewMiddleware`` will usually be a big hindrance to testing view
functions, due to the need for the CSRF token which must be sent with every POST
request. For this reason, Django's HTTP client for tests has been modified to
set a flag on requests which relaxes the middleware and the ``csrf_protect``
decorator so that they no longer rejects requests. In every other respect
(e.g. sending cookies etc.), they behave the same.
Limitations
===========
CsrfMiddleware requires Django's session framework to work. If you have
a custom authentication system that manually sets cookies and the like,
it won't help you.
Subdomains within a site will be able to set cookies on the client for the whole
domain. By setting the cookie and using a corresponding token, subdomains will
be able to circumvent the CSRF protection. The only way to avoid this is to
ensure that subdomains are controlled by trusted users (or, are at least unable
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 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. It may still be possible
to use the middleware, provided you can find some way to get the
CSRF token and ensure that is included when your form is submitted.
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.contrib.csrf.middleware.get_token` to get
the CSRF token and ensure it is included when your form is submitted.
Contrib and reusable apps
=========================
Because it is possible for the developer to turn off the ``CsrfViewMiddleware``,
all relevant views in contrib apps use the ``csrf_protect`` decorator to ensure
the security of these applications against CSRF. It is recommended that the
developers of other reusable apps that want the same guarantees also use the
``csrf_protect`` decorator on their views.

View File

@@ -177,7 +177,7 @@ Here's a full example template:
{% block content %}
<p>Step {{ step }} of {{ step_count }}</p>
<form action="." method="post">
<form action="." method="post">{% csrf_token %}
<table>
{{ form }}
</table>

View File

@@ -144,6 +144,44 @@ Default: ``600``
The default number of seconds to cache a page when the caching middleware or
``cache_page()`` decorator is used.
.. setting:: CSRF_COOKIE_NAME
CSRF_COOKIE_NAME
----------------
Default: ``'csrftoken'``
The name of the cookie to use for the CSRF authentication token. This can be whatever you
want. See :ref:`ref-contrib-csrf`.
.. setting:: CSRF_COOKIE_DOMAIN
CSRF_COOKIE_DOMAIN
------------------
Default: ``None``
The domain to be used when setting the CSRF cookie. This can be useful for
allowing cross-subdomain requests to be exluded from the normal cross site
request forgery protection. It should be set to a string such as
``".lawrence.com"`` to allow a POST request from a form on one subdomain to be
accepted by accepted by a view served from another subdomain.
.. setting:: CSRF_FAILURE_VIEW
CSRF_FAILURE_VIEW
-----------------
Default: ``'django.contrib.csrf.views.csrf_failure'``
A dotted path to the view function to be used when an incoming request
is rejected by the CSRF protection. The function should have this signature::
def csrf_failure(request, reason="")
where ``reason`` is a short message (intended for developers or logging, not for
end users) indicating the reason the request was rejected. See
:ref:`ref-contrib-csrf`.
.. setting:: DATABASE_ENGINE
DATABASE_ENGINE
@@ -751,6 +789,7 @@ Default::
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.csrf.middleware.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',)
A tuple of middleware classes to use. See :ref:`topics-http-middleware`.

View File

@@ -313,6 +313,13 @@ and return a dictionary of items to be merged into the context. By default,
"django.core.context_processors.i18n",
"django.core.context_processors.media")
.. versionadded:: 1.2
In addition to these, ``RequestContext`` always uses
``'django.contrib.csrf.context_processors.csrf'``. This is a security
related context processor required by the admin and other contrib apps, and,
in case of accidental misconfiguration, it is deliberately hardcoded in and
cannot be turned off by the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting.
Each processor is applied in order. That means, if one processor adds a
variable to the context and a second processor adds a variable with the same
name, the second will override the first. The default processors are explained
@@ -404,6 +411,14 @@ If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
``RequestContext`` will contain a variable ``MEDIA_URL``, providing the
value of the :setting:`MEDIA_URL` setting.
django.contrib.csrf.context_processors.csrf
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 1.2
This processor adds a token that is needed by the ``csrf_token`` template tag
for protection against :ref:`Cross Site Request Forgeries <ref-contrib-csrf>`.
django.core.context_processors.request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -53,6 +53,13 @@ Ignore everything between ``{% comment %}`` and ``{% endcomment %}``
.. templatetag:: cycle
csrf_token
~~~~~~~~~~
.. versionadded:: 1.2
This is described in the documentation for :ref:`Cross Site Request Forgeries <ref-contrib-csrf>`.
cycle
~~~~~

View File

@@ -2,6 +2,22 @@
Backwards-incompatible changes
==============================
CSRF Protection
---------------
There have been large changes to the way that CSRF protection works, detailed in
:ref:`the CSRF documentaton <ref-contrib-csrf>`. The following are the major
changes that developers must be aware of:
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated, and
will be removed completely in Django 1.4, in favour of a template tag that
should be inserted into forms.
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
default. This turns on CSRF protection by default, so that views that accept
POST requests need to be written to work with the middleware. Instructions
on how to do this are found in the CSRF docs.
LazyObject
----------

View File

@@ -767,7 +767,7 @@ the following line to your URLconf::
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url django.contrib.auth.views.login %}">
<form method="post" action="{% url django.contrib.auth.views.login %}">{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>

View File

@@ -29,6 +29,7 @@ created by :djadmin:`django-admin.py startproject <startproject>`::
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.csrf.middleware.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)