Fixed #20972 -- Make messages cookie follow session cookie secure/httponly

This commit is contained in:
Erik Romijn 2013-08-26 21:34:29 +02:00
parent b785a80d19
commit fa57266699
5 changed files with 35 additions and 7 deletions

View File

@ -79,7 +79,9 @@ class CookieStorage(BaseStorage):
""" """
if encoded_data: if encoded_data:
response.set_cookie(self.cookie_name, encoded_data, response.set_cookie(self.cookie_name, encoded_data,
domain=settings.SESSION_COOKIE_DOMAIN) domain=settings.SESSION_COOKIE_DOMAIN,
secure=settings.SESSION_COOKIE_SECURE or None,
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
else: else:
response.delete_cookie(self.cookie_name, response.delete_cookie(self.cookie_name,
domain=settings.SESSION_COOKIE_DOMAIN) domain=settings.SESSION_COOKIE_DOMAIN)

View File

@ -41,7 +41,7 @@ def stored_cookie_messages_count(storage, response):
return len(data) return len(data)
@override_settings(SESSION_COOKIE_DOMAIN='.example.com') @override_settings(SESSION_COOKIE_DOMAIN='.example.com', SESSION_COOKIE_SECURE=True, SESSION_COOKIE_HTTPONLY=True)
class CookieTest(BaseTests, TestCase): class CookieTest(BaseTests, TestCase):
storage_class = CookieStorage storage_class = CookieStorage
@ -56,10 +56,10 @@ class CookieTest(BaseTests, TestCase):
# Test that the message actually contains what we expect. # Test that the message actually contains what we expect.
self.assertEqual(list(storage), example_messages) self.assertEqual(list(storage), example_messages)
def test_domain(self): def test_cookie_setings(self):
""" """
Ensure that CookieStorage honors SESSION_COOKIE_DOMAIN. Ensure that CookieStorage honors SESSION_COOKIE_DOMAIN, SESSION_COOKIE_SECURE and SESSION_COOKIE_HTTPONLY
Refs #15618. Refs #15618 and #20972.
""" """
# Test before the messages have been consumed # Test before the messages have been consumed
storage = self.get_storage() storage = self.get_storage()
@ -69,8 +69,10 @@ class CookieTest(BaseTests, TestCase):
self.assertTrue('test' in response.cookies['messages'].value) self.assertTrue('test' in response.cookies['messages'].value)
self.assertEqual(response.cookies['messages']['domain'], '.example.com') self.assertEqual(response.cookies['messages']['domain'], '.example.com')
self.assertEqual(response.cookies['messages']['expires'], '') self.assertEqual(response.cookies['messages']['expires'], '')
self.assertEqual(response.cookies['messages']['secure'], True)
self.assertEqual(response.cookies['messages']['httponly'], True)
# Test after the messages have been consumed # Test deletion of the cookie (storing with an empty value) after the messages have been consumed
storage = self.get_storage() storage = self.get_storage()
response = self.get_response() response = self.get_response()
storage.add(constants.INFO, 'test') storage.add(constants.INFO, 'test')

View File

@ -376,3 +376,12 @@ behavior:
* :setting:`MESSAGE_LEVEL` * :setting:`MESSAGE_LEVEL`
* :setting:`MESSAGE_STORAGE` * :setting:`MESSAGE_STORAGE`
* :setting:`MESSAGE_TAGS` * :setting:`MESSAGE_TAGS`
.. versionadded:: 1.7
For backends that use cookies, the settings for the cookie are taken from
the session cookie settings:
* :setting:`SESSION_COOKIE_DOMAIN`
* :setting:`SESSION_COOKIE_SECURE`
* :setting:`SESSION_COOKIE_HTTPONLY`

View File

@ -2266,7 +2266,8 @@ See :ref:`message storage backends <message-storage-backends>` for more details.
The backends that use cookies -- The backends that use cookies --
:class:`~django.contrib.messages.storage.cookie.CookieStorage` and :class:`~django.contrib.messages.storage.cookie.CookieStorage` and
:class:`~django.contrib.messages.storage.fallback.FallbackStorage` -- :class:`~django.contrib.messages.storage.fallback.FallbackStorage` --
use the value of :setting:`SESSION_COOKIE_DOMAIN` when setting their cookies. use the value of :setting:`SESSION_COOKIE_DOMAIN`, :setting:`SESSION_COOKIE_SECURE`
and :setting:`SESSION_COOKIE_HTTPONLY` when setting their cookies.
.. setting:: MESSAGE_TAGS .. setting:: MESSAGE_TAGS
@ -2342,6 +2343,8 @@ standard domain cookies, existing user cookies will be set to the old
domain. This may result in them being unable to log in as long as these cookies domain. This may result in them being unable to log in as long as these cookies
persist. persist.
This setting also affects cookies set by :mod:`django.contrib.messages`.
.. setting:: SESSION_COOKIE_HTTPONLY .. setting:: SESSION_COOKIE_HTTPONLY
SESSION_COOKIE_HTTPONLY SESSION_COOKIE_HTTPONLY
@ -2359,6 +2362,10 @@ consistently by all browsers. However, when it is honored, it can be a
useful way to mitigate the risk of client side script accessing the useful way to mitigate the risk of client side script accessing the
protected cookie data. protected cookie data.
.. versionadded:: 1.7
This setting also affects cookies set by :mod:`django.contrib.messages`.
.. _HTTPOnly: https://www.owasp.org/index.php/HTTPOnly .. _HTTPOnly: https://www.owasp.org/index.php/HTTPOnly
.. setting:: SESSION_COOKIE_NAME .. setting:: SESSION_COOKIE_NAME
@ -2396,6 +2403,10 @@ Whether to use a secure cookie for the session cookie. If this is set to
``True``, the cookie will be marked as "secure," which means browsers may ``True``, the cookie will be marked as "secure," which means browsers may
ensure that the cookie is only sent under an HTTPS connection. ensure that the cookie is only sent under an HTTPS connection.
.. versionadded:: 1.7
This setting also affects cookies set by :mod:`django.contrib.messages`.
.. setting:: SESSION_ENGINE .. setting:: SESSION_ENGINE
SESSION_ENGINE SESSION_ENGINE

View File

@ -214,6 +214,10 @@ Minor features
* The :ttag:`widthratio` template tag now accepts an "as" parameter to capture * The :ttag:`widthratio` template tag now accepts an "as" parameter to capture
the result in a variable. the result in a variable.
* The backends for :mod:`django.contrib.messages` that use cookies, will now
follow the :setting:`SESSION_COOKIE_SECURE` and
:setting:`SESSION_COOKIE_HTTPONLY` settings.
Backwards incompatible changes in 1.7 Backwards incompatible changes in 1.7
===================================== =====================================