Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add CSRF_COOKIE_HTTPONLY config value #114

Closed
wants to merge 1 commit into from

2 participants

@saschpe

Fixes #15808, even if there is also strict referer checking in place, better safe than sorry.

@saschpe saschpe Add CSRF_COOKIE_HTTPONLY configuration value
Fixes #15808, even if there is also strict referer checking in place,
better safe than sorry.
02748fe
@adrianholovaty
Collaborator

I'd really prefer not to introduce another setting. Is there any other way to accomplish this?

@saschpe

Actually I added the config value just to be safe, altough I can't think of any situation where you wouldnt't want to set HttpOnly. However, I'd be fine without the config option, too ;-)

@adrianholovaty
Collaborator

Yeah, I'd say just hard-code it as HttpOnly. This would make the patch significantly smaller. :-) I'll close this one, but could you open a new pull request with a simpler patch?

@saschpe
@saschpe

Maybe it makes sense to keep the config value and set it to False by default, otherwise the current CSRF+Ajax recipe in the official Django documentation won't work (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax) because access to 'document.cookies' is restricted (obviously). Of course there are other ways to do it (like http://erlend.oftedal.no/blog/?blogid=118) but maybe this is worth discussing beforehand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 6, 2012
  1. @saschpe

    Add CSRF_COOKIE_HTTPONLY configuration value

    saschpe authored
    Fixes #15808, even if there is also strict referer checking in place,
    better safe than sorry.
This page is out of date. Refresh to see the latest.
View
1  django/conf/global_settings.py
@@ -531,6 +531,7 @@
CSRF_COOKIE_DOMAIN = None
CSRF_COOKIE_PATH = '/'
CSRF_COOKIE_SECURE = False
+CSRF_COOKIE_HTTPONLY = True
############
# MESSAGES #
View
3  django/middleware/csrf.py
@@ -208,7 +208,8 @@ def process_response(self, request, response):
max_age = 60 * 60 * 24 * 7 * 52,
domain=settings.CSRF_COOKIE_DOMAIN,
path=settings.CSRF_COOKIE_PATH,
- secure=settings.CSRF_COOKIE_SECURE
+ secure=settings.CSRF_COOKIE_SECURE,
+ httponly=settings.CSRF_COOKIE_HTTPONLY
)
# Content varies with the CSRF cookie, so set the Vary header.
patch_vary_headers(response, ('Cookie',))
View
11 docs/ref/contrib/csrf.txt
@@ -482,6 +482,17 @@ 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_COOKIE_HTTPONLY
+------------------
+
+.. versionadded:: 1.5
+
+Default: ``True``
+
+Whether to use HttpOnly flag on the CSRF cookie. If this is set to
+``True``, client-side JavaScript will not to be able to access the
+session cookie.
+
CSRF_FAILURE_VIEW
-----------------
View
13 docs/ref/settings.txt
@@ -362,6 +362,19 @@ 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_COOKIE_HTTPONLY
+
+CSRF_COOKIE_HTTPONLY
+------------------
+
+.. versionadded:: 1.5
+
+Default: ``True``
+
+Whether to use HttpOnly flag on the CSRF cookie. If this is set to
+``True``, client-side JavaScript will not to be able to access the
+session cookie. See :setting:`SESSION_COOKIE_HTTPONLY`.
+
.. setting:: CSRF_FAILURE_VIEW
CSRF_FAILURE_VIEW
View
4 tests/regressiontests/csrf_tests/tests.py
@@ -100,7 +100,8 @@ def test_process_response_get_token_used(self):
with self.settings(CSRF_COOKIE_NAME='myname',
CSRF_COOKIE_DOMAIN='.example.com',
CSRF_COOKIE_PATH='/test/',
- CSRF_COOKIE_SECURE=True):
+ CSRF_COOKIE_SECURE=True,
+ CSRF_COOKIE_HTTPONLY=True):
# token_view calls get_token() indirectly
CsrfViewMiddleware().process_view(req, token_view, (), {})
resp = token_view(req)
@@ -109,6 +110,7 @@ def test_process_response_get_token_used(self):
self.assertNotEqual(csrf_cookie, False)
self.assertEqual(csrf_cookie['domain'], '.example.com')
self.assertEqual(csrf_cookie['secure'], True)
+ self.assertEqual(csrf_cookie['httponly'], True)
self.assertEqual(csrf_cookie['path'], '/test/')
self.assertTrue('Cookie' in resp2.get('Vary',''))
Something went wrong with that request. Please try again.