A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/8d2f7cff76200cbd2337b2cf1707e383eb1fb54b below:

[3.2.x] Fixed CVE-2021-45452 -- Fixed potential path traversal in sto… · django/django@8d2f7cf · GitHub

File tree Expand file treeCollapse file tree 5 files changed

+45

-7

lines changed

Filter options

Expand file treeCollapse file tree 5 files changed

+45

-7

lines changed Original file line number Diff line number Diff line change

@@ -51,7 +51,10 @@ def save(self, name, content, max_length=None):

51 51

content = File(content, name)

52 52 53 53

name = self.get_available_name(name, max_length=max_length)

54 -

return self._save(name, content)

54 +

name = self._save(name, content)

55 +

# Ensure that the name returned from the storage system is still valid.

56 +

validate_file_name(name, allow_relative_path=True)

57 +

return name

55 58 56 59

# These methods are part of the public API, with default implementations.

57 60

@@ -75,6 +78,7 @@ def get_available_name(self, name, max_length=None):

75 78

Return a filename that's free on the target storage system and

76 79

available for new content to be written to.

77 80

"""

81 +

name = str(name).replace('\\', '/')

78 82

dir_name, file_name = os.path.split(name)

79 83

if '..' in pathlib.PurePath(dir_name).parts:

80 84

raise SuspiciousFileOperation("Detected path traversal attempt in '%s'" % dir_name)

@@ -108,6 +112,7 @@ def generate_filename(self, filename):

108 112

Validate the filename by calling get_valid_name() and return a filename

109 113

to be passed to the save() method.

110 114

"""

115 +

filename = str(filename).replace('\\', '/')

111 116

# `filename` may include a path as returned by FileField.upload_to.

112 117

dirname, filename = os.path.split(filename)

113 118

if '..' in pathlib.PurePath(dirname).parts:

@@ -297,6 +302,8 @@ def _save(self, name, content):

297 302

if self.file_permissions_mode is not None:

298 303

os.chmod(full_path, self.file_permissions_mode)

299 304 305 +

# Ensure the saved path is always relative to the storage root.

306 +

name = os.path.relpath(full_path, self.location)

300 307

# Store filenames with forward slashes, even on Windows.

301 308

return str(name).replace('\\', '/')

302 309 Original file line number Diff line number Diff line change

@@ -36,3 +36,12 @@ As a reminder, all untrusted user input should be validated before use.

36 36 37 37

This issue has severity "low" according to the :ref:`Django security policy

38 38

<security-disclosure>`.

39 + 40 +

CVE-2021-45452: Potential directory-traversal via ``Storage.save()``

41 +

====================================================================

42 + 43 +

``Storage.save()`` allowed directory-traversal if directly passed suitably

44 +

crafted file names.

45 + 46 +

This issue has severity "low" according to the :ref:`Django security policy

47 +

<security-disclosure>`.

Original file line number Diff line number Diff line change

@@ -36,3 +36,12 @@ As a reminder, all untrusted user input should be validated before use.

36 36 37 37

This issue has severity "low" according to the :ref:`Django security policy

38 38

<security-disclosure>`.

39 + 40 +

CVE-2021-45452: Potential directory-traversal via ``Storage.save()``

41 +

====================================================================

42 + 43 +

``Storage.save()`` allowed directory-traversal if directly passed suitably

44 +

crafted file names.

45 + 46 +

This issue has severity "low" according to the :ref:`Django security policy

47 +

<security-disclosure>`.

Original file line number Diff line number Diff line change

@@ -53,13 +53,20 @@ def test_storage_dangerous_paths(self):

53 53

s.generate_filename(file_name)

54 54 55 55

def test_storage_dangerous_paths_dir_name(self):

56 -

file_name = '/tmp/../path'

56 +

candidates = [

57 +

('tmp/../path', 'tmp/..'),

58 +

('tmp\\..\\path', 'tmp/..'),

59 +

('/tmp/../path', '/tmp/..'),

60 +

('\\tmp\\..\\path', '/tmp/..'),

61 +

]

57 62

s = FileSystemStorage()

58 -

msg = "Detected path traversal attempt in '/tmp/..'"

59 -

with self.assertRaisesMessage(SuspiciousFileOperation, msg):

60 -

s.get_available_name(file_name)

61 -

with self.assertRaisesMessage(SuspiciousFileOperation, msg):

62 -

s.generate_filename(file_name)

63 +

for file_name, path in candidates:

64 +

msg = "Detected path traversal attempt in '%s'" % path

65 +

with self.subTest(file_name=file_name):

66 +

with self.assertRaisesMessage(SuspiciousFileOperation, msg):

67 +

s.get_available_name(file_name)

68 +

with self.assertRaisesMessage(SuspiciousFileOperation, msg):

69 +

s.generate_filename(file_name)

63 70 64 71

def test_filefield_dangerous_filename(self):

65 72

candidates = [

Original file line number Diff line number Diff line change

@@ -297,6 +297,12 @@ def test_file_save_with_path(self):

297 297 298 298

self.storage.delete('path/to/test.file')

299 299 300 +

def test_file_save_abs_path(self):

301 +

test_name = 'path/to/test.file'

302 +

f = ContentFile('file saved with path')

303 +

f_name = self.storage.save(os.path.join(self.temp_dir, test_name), f)

304 +

self.assertEqual(f_name, test_name)

305 + 300 306

def test_save_doesnt_close(self):

301 307

with TemporaryUploadedFile('test', 'text/plain', 1, 'utf8') as file:

302 308

file.write(b'1')

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4