summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Plant <L.Plant.98@cantab.net>2011-05-09 23:00:22 +0000
committerLuke Plant <L.Plant.98@cantab.net>2011-05-09 23:00:22 +0000
commit8cbcf1d3a60a0ba1a6f3ddde9317ac07b67c6c5d (patch)
tree3c3167a0ee242211f6b2637e62c99ff34a896d15
parenta75120927e52210c062cd54d1cf2a6968b507cf5 (diff)
Fixed #14134 - ability to set cookie 'path' and 'secure' attributes of CSRF cookie
Thanks to cfattarsi for the report and initial patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16200 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/conf/global_settings.py4
-rw-r--r--django/middleware/csrf.py8
-rw-r--r--docs/ref/contrib/csrf.txt25
-rw-r--r--docs/ref/settings.txt29
-rw-r--r--tests/regressiontests/csrf_tests/tests.py18
5 files changed, 76 insertions, 8 deletions
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 477f13b675..88aa5a3e70 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -484,9 +484,11 @@ PASSWORD_RESET_TIMEOUT_DAYS = 3
# rejected by the CSRF middleware.
CSRF_FAILURE_VIEW = 'django.views.csrf.csrf_failure'
-# Name and domain for CSRF cookie.
+# Settings for CSRF cookie.
CSRF_COOKIE_NAME = 'csrftoken'
CSRF_COOKIE_DOMAIN = None
+CSRF_COOKIE_PATH = '/'
+CSRF_COOKIE_SECURE = False
############
# MESSAGES #
diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py
index 2f36f18e6c..e4cab6c08f 100644
--- a/django/middleware/csrf.py
+++ b/django/middleware/csrf.py
@@ -197,8 +197,12 @@ class CsrfViewMiddleware(object):
# Set the CSRF cookie even if it's already set, so we renew the expiry timer.
response.set_cookie(settings.CSRF_COOKIE_NAME,
- request.META["CSRF_COOKIE"], max_age = 60 * 60 * 24 * 7 * 52,
- domain=settings.CSRF_COOKIE_DOMAIN)
+ request.META["CSRF_COOKIE"],
+ max_age = 60 * 60 * 24 * 7 * 52,
+ domain=settings.CSRF_COOKIE_DOMAIN,
+ path=settings.CSRF_COOKIE_PATH,
+ secure=settings.CSRF_COOKIE_SECURE
+ )
# Content varies with the CSRF cookie, so set the Vary header.
patch_vary_headers(response, ('Cookie',))
response.csrf_processing_done = True
diff --git a/docs/ref/contrib/csrf.txt b/docs/ref/contrib/csrf.txt
index 88e9523719..b42dc26fbd 100644
--- a/docs/ref/contrib/csrf.txt
+++ b/docs/ref/contrib/csrf.txt
@@ -423,6 +423,31 @@ Default: ``'csrftoken'``
The name of the cookie to use for the CSRF authentication token. This can be
whatever you want.
+CSRF_COOKIE_PATH
+----------------
+
+.. versionadded:: 1.4
+
+Default: ``'/'``
+
+The path set on the CSRF cookie. This should either match the URL path of your
+Django installation or be a parent of that path.
+
+This is useful if you have multiple Django instances running under the same
+hostname. They can use different cookie paths, and each instance will only see
+its own CSRF cookie.
+
+CSRF_COOKIE_SECURE
+------------------
+
+.. versionadded:: 1.4
+
+Default: ``False``
+
+Whether to use a secure cookie for the CSRF cookie. If this is set to ``True``,
+the cookie will be marked as "secure," which means browsers may ensure that the
+cookie is only sent under an HTTPS connection.
+
CSRF_FAILURE_VIEW
-----------------
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index f8a5e0f640..f5f1226f21 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -340,6 +340,35 @@ Default: ``'csrftoken'``
The name of the cookie to use for the CSRF authentication token. This can be whatever you
want. See :doc:`/ref/contrib/csrf`.
+.. setting:: CSRF_COOKIE_PATH
+
+CSRF_COOKIE_PATH
+----------------
+
+.. versionadded:: 1.4
+
+Default: ``'/'``
+
+The path set on the CSRF cookie. This should either match the URL path of your
+Django installation or be a parent of that path.
+
+This is useful if you have multiple Django instances running under the same
+hostname. They can use different cookie paths, and each instance will only see
+its own CSRF cookie.
+
+.. setting:: CSRF_COOKIE_SECURE
+
+CSRF_COOKIE_SECURE
+------------------
+
+.. versionadded:: 1.4
+
+Default: ``False``
+
+Whether to use a secure cookie for the CSRF cookie. If this is set to ``True``,
+the cookie will be marked as "secure," which means browsers may ensure that the
+cookie is only sent under an HTTPS connection.
+
.. setting:: CSRF_FAILURE_VIEW
CSRF_FAILURE_VIEW
diff --git a/tests/regressiontests/csrf_tests/tests.py b/tests/regressiontests/csrf_tests/tests.py
index 1285c1ddac..8dc3fbbc1b 100644
--- a/tests/regressiontests/csrf_tests/tests.py
+++ b/tests/regressiontests/csrf_tests/tests.py
@@ -82,13 +82,21 @@ class CsrfViewMiddlewareTest(TestCase):
patched.
"""
req = self._get_GET_no_csrf_cookie_request()
- # token_view calls get_token() indirectly
- CsrfViewMiddleware().process_view(req, token_view, (), {})
- resp = token_view(req)
- resp2 = CsrfViewMiddleware().process_response(req, resp)
- csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
+ # Put tests for CSRF_COOKIE_* settings here
+ with self.settings(CSRF_COOKIE_NAME='myname',
+ CSRF_COOKIE_DOMAIN='.example.com',
+ CSRF_COOKIE_PATH='/test/',
+ CSRF_COOKIE_SECURE=True):
+ # token_view calls get_token() indirectly
+ CsrfViewMiddleware().process_view(req, token_view, (), {})
+ resp = token_view(req)
+ resp2 = CsrfViewMiddleware().process_response(req, resp)
+ csrf_cookie = resp2.cookies.get('myname', False)
self.assertNotEqual(csrf_cookie, False)
+ self.assertEqual(csrf_cookie['domain'], '.example.com')
+ self.assertEqual(csrf_cookie['secure'], True)
+ self.assertEqual(csrf_cookie['path'], '/test/')
self.assertTrue('Cookie' in resp2.get('Vary',''))
def test_process_response_get_token_not_used(self):