From 316bc3fc9437c5960c24baceb93c73f1939711e4 Mon Sep 17 00:00:00 2001 From: Florian Apolloner Date: Wed, 11 Nov 2015 20:10:55 +0100 Subject: [PATCH] Fixed a settings leak possibility in the date template filter. This is a security fix. --- django/utils/formats.py | 20 ++++++++++++++++++++ docs/releases/1.7.11.txt | 15 ++++++++++++++- docs/releases/1.8.7.txt | 15 ++++++++++++++- tests/i18n/tests.py | 3 +++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/django/utils/formats.py b/django/utils/formats.py index d2bdda458e00f..8334682e68418 100644 --- a/django/utils/formats.py +++ b/django/utils/formats.py @@ -30,6 +30,24 @@ } +FORMAT_SETTINGS = frozenset([ + 'DECIMAL_SEPARATOR', + 'THOUSAND_SEPARATOR', + 'NUMBER_GROUPING', + 'FIRST_DAY_OF_WEEK', + 'MONTH_DAY_FORMAT', + 'TIME_FORMAT', + 'DATE_FORMAT', + 'DATETIME_FORMAT', + 'SHORT_DATE_FORMAT', + 'SHORT_DATETIME_FORMAT', + 'YEAR_MONTH_FORMAT', + 'DATE_INPUT_FORMATS', + 'TIME_INPUT_FORMATS', + 'DATETIME_INPUT_FORMATS', +]) + + def reset_format_cache(): """Clear any cached formats. @@ -92,6 +110,8 @@ def get_format(format_type, lang=None, use_l10n=None): be localized (or not), overriding the value of settings.USE_L10N. """ format_type = force_str(format_type) + if format_type not in FORMAT_SETTINGS: + return format_type if use_l10n or (use_l10n is None and settings.USE_L10N): if lang is None: lang = get_language() diff --git a/docs/releases/1.7.11.txt b/docs/releases/1.7.11.txt index 7c6153eab1d91..8f2f5e7541eab 100644 --- a/docs/releases/1.7.11.txt +++ b/docs/releases/1.7.11.txt @@ -4,7 +4,20 @@ Django 1.7.11 release notes *Under development* -Django 1.7.11 fixes a data loss bug in 1.7.10. +Django 1.7.11 fixes a security issue and a data loss bug in 1.7.10. + +Fixed settings leak possibility in ``date`` template filter +=========================================================== + +If an application allows users to specify an unvalidated format for dates and +passes this format to the :tfilter:`date` filter, e.g. +``{{ last_updated|date:user_date_format }}``, then a malicious user could +obtain any secret in the application's settings by specifying a settings key +instead of a date format. e.g. ``"SECRET_KEY"`` instead of ``"j/m/Y"``. + +To remedy this, the underlying function used by the ``date`` template filter, +``django.utils.formats.get_format()``, now only allows accessing the date/time +formatting settings. Bugfixes ======== diff --git a/docs/releases/1.8.7.txt b/docs/releases/1.8.7.txt index 25f7712f10636..77d5e9f901ec9 100644 --- a/docs/releases/1.8.7.txt +++ b/docs/releases/1.8.7.txt @@ -4,11 +4,24 @@ Django 1.8.7 release notes *Under development* -Django 1.8.7 fixes several bugs in 1.8.6. +Django 1.8.7 fixes a security issue and several bugs in 1.8.6. Additionally, Django's vendored version of six, :mod:`django.utils.six`, has been upgraded to the latest release (1.10.0). +Fixed settings leak possibility in ``date`` template filter +=========================================================== + +If an application allows users to specify an unvalidated format for dates and +passes this format to the :tfilter:`date` filter, e.g. +``{{ last_updated|date:user_date_format }}``, then a malicious user could +obtain any secret in the application's settings by specifying a settings key +instead of a date format. e.g. ``"SECRET_KEY"`` instead of ``"j/m/Y"``. + +To remedy this, the underlying function used by the ``date`` template filter, +``django.utils.formats.get_format()``, now only allows accessing the date/time +formatting settings. + Bugfixes ======== diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index 1de7b11b8117b..fd332c596e77d 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -1249,6 +1249,9 @@ def test_localized_as_text_as_hidden_input(self): '' ) + def test_format_arbitrary_settings(self): + self.assertEqual(get_format('DEBUG'), 'DEBUG') + class MiscTests(SimpleTestCase):