+51
-3
lines changedFilter options
+51
-3
lines changed Original file line number Diff line number Diff line change
@@ -27,6 +27,8 @@
27
27
import tarfile
28
28
import zipfile
29
29
30
+
from django.core.exceptions import SuspiciousOperation
31
+
30
32
31
33
class ArchiveException(Exception):
32
34
"""
@@ -133,6 +135,13 @@ def has_leading_dir(self, paths):
133
135
return False
134
136
return True
135
137
138
+
def target_filename(self, to_path, name):
139
+
target_path = os.path.abspath(to_path)
140
+
filename = os.path.abspath(os.path.join(target_path, name))
141
+
if not filename.startswith(target_path):
142
+
raise SuspiciousOperation("Archive contains invalid path: '%s'" % name)
143
+
return filename
144
+
136
145
def extract(self):
137
146
raise NotImplementedError('subclasses of BaseArchive must provide an extract() method')
138
147
@@ -155,7 +164,7 @@ def extract(self, to_path):
155
164
name = member.name
156
165
if leading:
157
166
name = self.split_leading_dir(name)[1]
158
-
filename = os.path.join(to_path, name)
167
+
filename = self.target_filename(to_path, name)
159
168
if member.isdir():
160
169
if filename and not os.path.exists(filename):
161
170
os.makedirs(filename)
@@ -198,11 +207,13 @@ def extract(self, to_path):
198
207
info = self._archive.getinfo(name)
199
208
if leading:
200
209
name = self.split_leading_dir(name)[1]
201
-
filename = os.path.join(to_path, name)
210
+
if not name:
211
+
continue
212
+
filename = self.target_filename(to_path, name)
202
213
dirname = os.path.dirname(filename)
203
214
if dirname and not os.path.exists(dirname):
204
215
os.makedirs(dirname)
205
-
if filename.endswith(('/', '\\')):
216
+
if name.endswith(('/', '\\')):
206
217
# A directory
207
218
if not os.path.exists(filename):
208
219
os.makedirs(filename)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
1
+
===========================
2
+
Django 2.2.18 release notes
3
+
===========================
4
+
5
+
*February 1, 2021*
6
+
7
+
Django 2.2.18 fixes a security issue with severity "low" in 2.2.17.
8
+
9
+
CVE-2021-3281: Potential directory-traversal via ``archive.extract()``
10
+
======================================================================
11
+
12
+
The ``django.utils.archive.extract()`` function, used by
13
+
:option:`startapp --template` and :option:`startproject --template`, allowed
14
+
directory-traversal via an archive with absolute paths or relative paths with
15
+
dot segments.
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ versions of the documentation contain the release notes for any later releases.
25
25
.. toctree::
26
26
:maxdepth: 1
27
27
28
+
2.2.18
28
29
2.2.17
29
30
2.2.16
30
31
2.2.15
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@
5
5
import tempfile
6
6
import unittest
7
7
8
+
from django.core.exceptions import SuspiciousOperation
9
+
from django.test import SimpleTestCase
8
10
from django.utils.archive import Archive, extract
9
11
10
12
TEST_DIR = os.path.join(os.path.dirname(__file__), 'archives')
@@ -87,3 +89,22 @@ class TestGzipTar(ArchiveTester, unittest.TestCase):
87
89
88
90
class TestBzip2Tar(ArchiveTester, unittest.TestCase):
89
91
archive = 'foobar.tar.bz2'
92
+
93
+
94
+
class TestArchiveInvalid(SimpleTestCase):
95
+
def test_extract_function_traversal(self):
96
+
archives_dir = os.path.join(os.path.dirname(__file__), 'traversal_archives')
97
+
tests = [
98
+
('traversal.tar', '..'),
99
+
('traversal_absolute.tar', '/tmp/evil.py'),
100
+
]
101
+
if sys.platform == 'win32':
102
+
tests += [
103
+
('traversal_disk_win.tar', 'd:evil.py'),
104
+
('traversal_disk_win.zip', 'd:evil.py'),
105
+
]
106
+
msg = "Archive contains invalid path: '%s'"
107
+
for entry, invalid_path in tests:
108
+
with self.subTest(entry), tempfile.TemporaryDirectory() as tmpdir:
109
+
with self.assertRaisesMessage(SuspiciousOperation, msg % invalid_path):
110
+
extract(os.path.join(archives_dir, entry), tmpdir)
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