Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed Django 1.1 fallback for CSRF checks.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15948 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 21ef64e34c1c84bd7beb07531694d3f22fc42ffd 1 parent 4550f95
@spookylukey spookylukey authored
Showing with 26 additions and 99 deletions.
  1. +23 −52 django/middleware/csrf.py
  2. +3 −47 tests/regressiontests/csrf_tests/tests.py
View
75 django/middleware/csrf.py
@@ -34,7 +34,6 @@
REASON_NO_REFERER = "Referer checking failed - no Referer."
REASON_BAD_REFERER = "Referer checking failed - %s does not match %s."
-REASON_NO_COOKIE = "No CSRF or session cookie."
REASON_NO_CSRF_COOKIE = "CSRF cookie not set."
REASON_BAD_TOKEN = "CSRF token missing or incorrect."
@@ -105,22 +104,14 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
if getattr(request, 'csrf_processing_done', False):
return None
- # If the user doesn't have a CSRF cookie, generate one and store it in the
- # request, so it's available to the view. We'll store it in a cookie when
- # we reach the response.
try:
- # In case of cookies from untrusted sources, we strip anything
- # dangerous at this point, so that the cookie + token will have the
- # same, sanitized value.
- request.META["CSRF_COOKIE"] = _sanitize_token(request.COOKIES[settings.CSRF_COOKIE_NAME])
- cookie_is_new = False
+ csrf_token = _sanitize_token(request.COOKIES[settings.CSRF_COOKIE_NAME])
+ # Use same token next time
+ request.META['CSRF_COOKIE'] = csrf_token
except KeyError:
- # No cookie, so create one. This will be sent with the next
- # response.
+ csrf_token = None
+ # Generate token and store it in the request, so it's available to the view.
request.META["CSRF_COOKIE"] = _get_new_csrf_key()
- # Set a flag to allow us to fall back and allow the session id in
- # place of a CSRF cookie for this request only.
- cookie_is_new = True
# Wait until request.META["CSRF_COOKIE"] has been manipulated before
# bailing out, so that get_token still works
@@ -173,27 +164,17 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
)
return self._reject(request, reason)
- # If the user didn't already have a CSRF cookie, then fall back to
- # the Django 1.1 method (hash of session ID), so a request is not
- # rejected if the form was sent to the user before upgrading to the
- # Django 1.2 method (session independent nonce)
- if cookie_is_new:
- try:
- session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
- csrf_token = _make_legacy_session_token(session_id)
- except KeyError:
- # No CSRF cookie and no session cookie. For POST requests,
- # we insist on a CSRF cookie, and in this way we can avoid
- # all CSRF attacks, including login CSRF.
- logger.warning('Forbidden (%s): %s' % (REASON_NO_COOKIE, request.path),
- extra={
- 'status_code': 403,
- 'request': request,
- }
- )
- return self._reject(request, REASON_NO_COOKIE)
- else:
- csrf_token = request.META["CSRF_COOKIE"]
+ if csrf_token is None:
+ # No CSRF cookie. For POST requests, we insist on a CSRF cookie,
+ # and in this way we can avoid all CSRF attacks, including login
+ # CSRF.
+ logger.warning('Forbidden (%s): %s' % (REASON_NO_CSRF_COOKIE, request.path),
+ extra={
+ 'status_code': 403,
+ 'request': request,
+ }
+ )
+ return self._reject(request, REASON_NO_CSRF_COOKIE)
# check incoming token
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
@@ -202,23 +183,13 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
if not constant_time_compare(request_csrf_token, csrf_token):
- if cookie_is_new:
- # probably a problem setting the CSRF cookie
- logger.warning('Forbidden (%s): %s' % (REASON_NO_CSRF_COOKIE, request.path),
- extra={
- 'status_code': 403,
- 'request': request,
- }
- )
- return self._reject(request, REASON_NO_CSRF_COOKIE)
- else:
- logger.warning('Forbidden (%s): %s' % (REASON_BAD_TOKEN, request.path),
- extra={
- 'status_code': 403,
- 'request': request,
- }
- )
- return self._reject(request, REASON_BAD_TOKEN)
+ logger.warning('Forbidden (%s): %s' % (REASON_BAD_TOKEN, request.path),
+ extra={
+ 'status_code': 403,
+ 'request': request,
+ }
+ )
+ return self._reject(request, REASON_BAD_TOKEN)
return self._accept(request)
View
50 tests/regressiontests/csrf_tests/tests.py
@@ -6,8 +6,6 @@
from django.middleware.csrf import CsrfMiddleware, CsrfViewMiddleware
from django.views.decorators.csrf import csrf_exempt, csrf_view_exempt, requires_csrf_token
from django.core.context_processors import csrf
-from django.contrib.sessions.middleware import SessionMiddleware
-from django.utils.importlib import import_module
from django.conf import settings
from django.template import RequestContext, Template
@@ -62,14 +60,6 @@ class CsrfMiddlewareTest(TestCase):
_csrf_id_cookie = "<1>\xc2\xa1"
_csrf_id = "1"
- # This is a valid session token for this ID and secret key. This was generated using
- # the old code that we're to be backwards-compatible with. Don't use the CSRF code
- # to generate this hash, or we're merely testing the code against itself and not
- # checking backwards-compatibility. This is also the output of (echo -n test1 | md5sum).
- _session_token = "5a105e8b9d40e1329780d62ea2265d8a"
- _session_id = "1"
- _secret_key_for_session_test= "test"
-
def setUp(self):
self.save_warnings_state()
warnings.filterwarnings('ignore', category=DeprecationWarning,
@@ -101,17 +91,6 @@ def _get_POST_request_with_token(self):
req.POST['csrfmiddlewaretoken'] = self._csrf_id
return req
- def _get_POST_session_request_with_token(self):
- req = self._get_POST_no_csrf_cookie_request()
- req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id
- req.POST['csrfmiddlewaretoken'] = self._session_token
- return req
-
- def _get_POST_session_request_no_token(self):
- req = self._get_POST_no_csrf_cookie_request()
- req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id
- return req
-
def _check_token_present(self, response, csrf_id=None):
self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id))
@@ -226,10 +205,10 @@ def test_process_response_exempt_view(self):
self.assertEqual(resp_content, resp2.content)
# Check the request processing
- def test_process_request_no_session_no_csrf_cookie(self):
+ def test_process_request_no_csrf_cookie(self):
"""
- Check that if neither a CSRF cookie nor a session cookie are present,
- the middleware rejects the incoming request. This will stop login CSRF.
+ Check that if no CSRF cookies is present, the middleware rejects the
+ incoming request. This will stop login CSRF.
"""
req = self._get_POST_no_csrf_cookie_request()
req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
@@ -252,29 +231,6 @@ def test_process_request_csrf_cookie_and_token(self):
req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
self.assertEqual(None, req2)
- def test_process_request_session_cookie_no_csrf_cookie_token(self):
- """
- When no CSRF cookie exists, but the user has a session, check that a token
- using the session cookie as a legacy CSRF cookie is accepted.
- """
- orig_secret_key = settings.SECRET_KEY
- settings.SECRET_KEY = self._secret_key_for_session_test
- try:
- req = self._get_POST_session_request_with_token()
- req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
- self.assertEqual(None, req2)
- finally:
- settings.SECRET_KEY = orig_secret_key
-
- def test_process_request_session_cookie_no_csrf_cookie_no_token(self):
- """
- Check that if a session cookie is present but no token and no CSRF cookie,
- the request is rejected.
- """
- req = self._get_POST_session_request_no_token()
- req2 = CsrfMiddleware().process_view(req, post_form_view, (), {})
- self.assertEqual(403, req2.status_code)
-
def test_process_request_csrf_cookie_no_token_exempt_view(self):
"""
Check that if a CSRF cookie is present and no token, but the csrf_exempt
Please sign in to comment.
Something went wrong with that request. Please try again.