diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-08-21 12:43:45 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-08-25 11:09:40 +0200 |
| commit | a3aebfdc8153dc230686b6d2454ccd32ed4c9e6f (patch) | |
| tree | 983d19b0902cde5d010ff6905cfe7d75ce7f07f9 | |
| parent | 375657a71c889c588f723469bd868bd1d40c369f (diff) | |
[2.2.x] Fixed CVE-2020-24584 -- Fixed permission escalation in intermediate-level directories of the file system cache on Python 3.7+.
Backport of f56b57976133129b0b351a38bba4ac882badabf0 from master.
| -rw-r--r-- | django/core/cache/backends/filebased.py | 5 | ||||
| -rw-r--r-- | docs/releases/2.2.16.txt | 9 | ||||
| -rw-r--r-- | tests/cache/tests.py | 26 |
3 files changed, 38 insertions, 2 deletions
diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index ca8b006577..012b54e8cf 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -114,10 +114,15 @@ class FileBasedCache(BaseCache): def _createdir(self): if not os.path.exists(self._dir): + # Set the umask because os.makedirs() doesn't apply the "mode" argument + # to intermediate-level directories. + old_umask = os.umask(0o077) try: os.makedirs(self._dir, 0o700) except FileExistsError: pass + finally: + os.umask(old_umask) def _key_to_file(self, key, version=None): """ diff --git a/docs/releases/2.2.16.txt b/docs/releases/2.2.16.txt index f0c3ec894a..f531871d1a 100644 --- a/docs/releases/2.2.16.txt +++ b/docs/releases/2.2.16.txt @@ -4,7 +4,7 @@ Django 2.2.16 release notes *Expected September 1, 2020* -Django 2.2.16 fixes a security issue and two data loss bugs in 2.2.15. +Django 2.2.16 fixes two security issues and two data loss bugs in 2.2.15. CVE-2020-24583: Incorrect permissions on intermediate-level directories on Python 3.7+ ====================================================================================== @@ -17,6 +17,13 @@ files and to intermediate-level collected static directories when using the You should review and manually fix permissions on existing intermediate-level directories. +CVE-2020-24584: Permission escalation in intermediate-level directories of the file system cache on Python 3.7+ +=============================================================================================================== + +On Python 3.7+, the intermediate-level directories of the file system cache had +the system's standard umask rather than ``0o077`` (no group or others +permissions). + Bugfixes ======== diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 0581aa37aa..539247d6af 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -6,11 +6,13 @@ import os import pickle import re import shutil +import sys import tempfile import threading import time import unittest -from unittest import mock +from pathlib import Path +from unittest import mock, skipIf from django.conf import settings from django.core import management, signals @@ -1430,6 +1432,28 @@ class FileBasedCacheTests(BaseCacheTests, TestCase): # Returns the default instead of erroring. self.assertEqual(cache.get('foo', 'baz'), 'baz') + @skipIf( + sys.platform == 'win32', + 'Windows only partially supports umasks and chmod.', + ) + def test_cache_dir_permissions(self): + os.rmdir(self.dirname) + dir_path = Path(self.dirname) / 'nested' / 'filebasedcache' + for cache_params in settings.CACHES.values(): + cache_params['LOCATION'] = str(dir_path) + setting_changed.send(self.__class__, setting='CACHES', enter=False) + cache.set('foo', 'bar') + self.assertIs(dir_path.exists(), True) + tests = [ + dir_path, + dir_path.parent, + dir_path.parent.parent, + ] + for directory in tests: + with self.subTest(directory=directory): + dir_mode = directory.stat().st_mode & 0o777 + self.assertEqual(dir_mode, 0o700) + def test_get_does_not_ignore_non_filenotfound_exceptions(self): with mock.patch('builtins.open', side_effect=IOError): with self.assertRaises(IOError): |
