summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRan Benita <ran234@gmail.com>2019-04-01 12:29:10 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-04-08 11:26:06 +0200
commit19fc6376ce67d01ca37a91ef2f55ef769f50513a (patch)
treea40bb59e08bec7f9c6358d078a7e3157760b7993
parentcef3f2d3c64055c9fc1757fd61dba24b557a2add (diff)
Fixed #30304 -- Added support for the HttpOnly, SameSite, and Secure flags on language cookies.
-rw-r--r--django/conf/global_settings.py3
-rw-r--r--django/views/i18n.py3
-rw-r--r--docs/ref/settings.txt45
-rw-r--r--docs/releases/3.0.txt6
-rw-r--r--docs/topics/i18n/translation.txt3
-rw-r--r--tests/view_tests/tests/test_i18n.py9
6 files changed, 68 insertions, 1 deletions
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index dd368584e5..61d08ddba5 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -154,6 +154,9 @@ LANGUAGE_COOKIE_NAME = 'django_language'
LANGUAGE_COOKIE_AGE = None
LANGUAGE_COOKIE_DOMAIN = None
LANGUAGE_COOKIE_PATH = '/'
+LANGUAGE_COOKIE_SECURE = False
+LANGUAGE_COOKIE_HTTPONLY = False
+LANGUAGE_COOKIE_SAMESITE = None
# If you set this to True, Django will format dates, numbers and calendars
diff --git a/django/views/i18n.py b/django/views/i18n.py
index ce5691632c..e3ef40b2fc 100644
--- a/django/views/i18n.py
+++ b/django/views/i18n.py
@@ -55,6 +55,9 @@ def set_language(request):
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN,
+ secure=settings.LANGUAGE_COOKIE_SECURE,
+ httponly=settings.LANGUAGE_COOKIE_HTTPONLY,
+ samesite=settings.LANGUAGE_COOKIE_SAMESITE,
)
return response
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 5c87aa5d24..ae7436696e 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1766,6 +1766,21 @@ permanently (via the :setting:`LANGUAGE_COOKIE_NAME` setting) and to add
a middleware that copies the value from the old cookie to a new one and then
deletes the old one.
+.. setting:: LANGUAGE_COOKIE_HTTPONLY
+
+``LANGUAGE_COOKIE_HTTPONLY``
+----------------------------
+
+.. versionadded:: 3.0
+
+Default: ``False``
+
+Whether to use ``HttpOnly`` flag on the language cookie. If this is set to
+``True``, client-side JavaScript will not to be able to access the language
+cookie.
+
+See :setting:`SESSION_COOKIE_HTTPONLY` for details on ``HttpOnly``.
+
.. setting:: LANGUAGE_COOKIE_NAME
``LANGUAGE_COOKIE_NAME``
@@ -1800,6 +1815,33 @@ permanently (via the :setting:`LANGUAGE_COOKIE_NAME` setting), and to add
a middleware that copies the value from the old cookie to a new one and then
deletes the one.
+.. setting:: LANGUAGE_COOKIE_SAMESITE
+
+``LANGUAGE_COOKIE_SAMESITE``
+----------------------------
+
+.. versionadded:: 3.0
+
+Default: ``None``
+
+The value of the `SameSite`_ flag on the language cookie. This flag prevents the
+cookie from being sent in cross-site requests.
+
+See :setting:`SESSION_COOKIE_SAMESITE` for details about ``SameSite``.
+
+.. setting:: LANGUAGE_COOKIE_SECURE
+
+``LANGUAGE_COOKIE_SECURE``
+--------------------------
+
+.. versionadded:: 3.0
+
+Default: ``False``
+
+Whether to use a secure cookie for the language 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:: LANGUAGES
``LANGUAGES``
@@ -3402,8 +3444,11 @@ Globalization (``i18n``/``l10n``)
* :setting:`LANGUAGE_CODE`
* :setting:`LANGUAGE_COOKIE_AGE`
* :setting:`LANGUAGE_COOKIE_DOMAIN`
+* :setting:`LANGUAGE_COOKIE_HTTPONLY`
* :setting:`LANGUAGE_COOKIE_NAME`
* :setting:`LANGUAGE_COOKIE_PATH`
+* :setting:`LANGUAGE_COOKIE_SAMESITE`
+* :setting:`LANGUAGE_COOKIE_SECURE`
* :setting:`LANGUAGES`
* :setting:`LANGUAGES_BIDI`
* :setting:`LOCALE_PATHS`
diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt
index 11257b70be..d7ad7a8cf7 100644
--- a/docs/releases/3.0.txt
+++ b/docs/releases/3.0.txt
@@ -153,7 +153,11 @@ Generic Views
Internationalization
~~~~~~~~~~~~~~~~~~~~
-* ...
+* Added the :setting:`LANGUAGE_COOKIE_HTTPONLY`,
+ :setting:`LANGUAGE_COOKIE_SAMESITE`, and :setting:`LANGUAGE_COOKIE_SECURE`
+ settings to set the ``HttpOnly``, ``SameSite``, and ``Secure`` flags on
+ language cookies. The default values of these settings preserve the previous
+ behavior.
Management Commands
~~~~~~~~~~~~~~~~~~~
diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt
index 00338100f9..bafa4bdaf1 100644
--- a/docs/topics/i18n/translation.txt
+++ b/docs/topics/i18n/translation.txt
@@ -1896,7 +1896,10 @@ A number of settings can be used to adjust language cookie options:
* :setting:`LANGUAGE_COOKIE_NAME`
* :setting:`LANGUAGE_COOKIE_AGE`
* :setting:`LANGUAGE_COOKIE_DOMAIN`
+* :setting:`LANGUAGE_COOKIE_HTTPONLY`
* :setting:`LANGUAGE_COOKIE_PATH`
+* :setting:`LANGUAGE_COOKIE_SAMESITE`
+* :setting:`LANGUAGE_COOKIE_SECURE`
Implementation notes
====================
diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py
index 7b36181800..1362bc2911 100644
--- a/tests/view_tests/tests/test_i18n.py
+++ b/tests/view_tests/tests/test_i18n.py
@@ -45,6 +45,9 @@ class SetLanguageTests(TestCase):
self.assertEqual(language_cookie['domain'], '')
self.assertEqual(language_cookie['path'], '/')
self.assertEqual(language_cookie['max-age'], '')
+ self.assertEqual(language_cookie['httponly'], '')
+ self.assertEqual(language_cookie['samesite'], '')
+ self.assertEqual(language_cookie['secure'], '')
def test_setlang_unsafe_next(self):
"""
@@ -175,6 +178,9 @@ class SetLanguageTests(TestCase):
'LANGUAGE_COOKIE_AGE': 3600 * 7 * 2,
'LANGUAGE_COOKIE_DOMAIN': '.example.com',
'LANGUAGE_COOKIE_PATH': '/test/',
+ 'LANGUAGE_COOKIE_HTTPONLY': True,
+ 'LANGUAGE_COOKIE_SAMESITE': 'Strict',
+ 'LANGUAGE_COOKIE_SECURE': True,
}
with self.settings(**test_settings):
post_data = {'language': 'pl', 'next': '/views/'}
@@ -184,6 +190,9 @@ class SetLanguageTests(TestCase):
self.assertEqual(language_cookie['domain'], '.example.com')
self.assertEqual(language_cookie['path'], '/test/')
self.assertEqual(language_cookie['max-age'], 3600 * 7 * 2)
+ self.assertEqual(language_cookie['httponly'], True)
+ self.assertEqual(language_cookie['samesite'], 'Strict')
+ self.assertEqual(language_cookie['secure'], True)
def test_setlang_decodes_http_referer_url(self):
"""