Skip to content

Commit 7a9f479

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 8d8d4a4 commit 7a9f479

File tree

1 file changed

+75
-76
lines changed

1 file changed

+75
-76
lines changed

tests/apps/test_download_and_extract.py

Lines changed: 75 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
import tempfile
1515
import unittest
16-
import os
1716
import zipfile
1817
import tarfile
1918
from pathlib import Path
@@ -71,181 +70,181 @@ def test_default(self, key, file_type):
7170

7271
class TestPathTraversalProtection(unittest.TestCase):
7372
"""Test cases for path traversal attack protection in extractall function."""
74-
73+
7574
def test_valid_zip_extraction(self):
7675
"""Test that valid zip files extract successfully without raising exceptions."""
7776
with tempfile.TemporaryDirectory() as tmp_dir:
7877
# Create a valid zip file
7978
zip_path = Path(tmp_dir) / "valid_test.zip"
8079
extract_dir = Path(tmp_dir) / "extract"
8180
extract_dir.mkdir()
82-
81+
8382
# Create zip with normal file structure
8483
with zipfile.ZipFile(zip_path, 'w') as zf:
8584
zf.writestr("normal_file.txt", "This is a normal file")
8685
zf.writestr("subdir/nested_file.txt", "This is a nested file")
8786
zf.writestr("another_file.json", '{"key": "value"}')
88-
87+
8988
# This should not raise any exception
9089
try:
9190
extractall(str(zip_path), str(extract_dir))
92-
91+
9392
# Verify files were extracted correctly
9493
self.assertTrue((extract_dir / "normal_file.txt").exists())
9594
self.assertTrue((extract_dir / "subdir" / "nested_file.txt").exists())
9695
self.assertTrue((extract_dir / "another_file.json").exists())
97-
96+
9897
# Verify content
99-
with open(extract_dir / "normal_file.txt", 'r') as f:
98+
with open(extract_dir / "normal_file.txt") as f:
10099
self.assertEqual(f.read(), "This is a normal file")
101-
100+
102101
except Exception as e:
103102
self.fail(f"Valid zip extraction should not raise exception: {e}")
104-
103+
105104
def test_malicious_zip_path_traversal(self):
106105
"""Test that malicious zip files with path traversal attempts raise ValueError."""
107106
with tempfile.TemporaryDirectory() as tmp_dir:
108107
# Create malicious zip file with path traversal
109108
zip_path = Path(tmp_dir) / "malicious_test.zip"
110109
extract_dir = Path(tmp_dir) / "extract"
111110
extract_dir.mkdir()
112-
111+
113112
# Create zip with malicious paths
114113
with zipfile.ZipFile(zip_path, 'w') as zf:
115114
# Try to write outside extraction directory
116115
zf.writestr("../../../etc/malicious.txt", "malicious content")
117116
zf.writestr("normal_file.txt", "normal content")
118-
117+
119118
# This should raise ValueError due to path traversal detection
120119
with self.assertRaises(ValueError) as context:
121120
extractall(str(zip_path), str(extract_dir))
122-
121+
123122
self.assertIn("unsafe path", str(context.exception).lower())
124-
123+
125124
def test_valid_tar_extraction(self):
126125
"""Test that valid tar files extract successfully without raising exceptions."""
127126
with tempfile.TemporaryDirectory() as tmp_dir:
128127
# Create a valid tar file
129128
tar_path = Path(tmp_dir) / "valid_test.tar.gz"
130129
extract_dir = Path(tmp_dir) / "extract"
131130
extract_dir.mkdir()
132-
131+
133132
# Create tar with normal file structure
134133
with tarfile.open(tar_path, 'w:gz') as tf:
135134
# Create temporary files to add to tar
136135
temp_file1 = Path(tmp_dir) / "temp1.txt"
137136
temp_file1.write_text("This is a normal file")
138137
tf.add(temp_file1, arcname="normal_file.txt")
139-
138+
140139
temp_file2 = Path(tmp_dir) / "temp2.txt"
141140
temp_file2.write_text("This is a nested file")
142141
tf.add(temp_file2, arcname="subdir/nested_file.txt")
143-
142+
144143
# This should not raise any exception
145144
try:
146145
extractall(str(tar_path), str(extract_dir))
147-
146+
148147
# Verify files were extracted correctly
149148
self.assertTrue((extract_dir / "normal_file.txt").exists())
150149
self.assertTrue((extract_dir / "subdir" / "nested_file.txt").exists())
151-
150+
152151
# Verify content
153-
with open(extract_dir / "normal_file.txt", 'r') as f:
152+
with open(extract_dir / "normal_file.txt") as f:
154153
self.assertEqual(f.read(), "This is a normal file")
155-
154+
156155
except Exception as e:
157156
self.fail(f"Valid tar extraction should not raise exception: {e}")
158-
157+
159158
def test_malicious_tar_path_traversal(self):
160159
"""Test that malicious tar files with path traversal attempts raise ValueError."""
161160
with tempfile.TemporaryDirectory() as tmp_dir:
162161
# Create malicious tar file with path traversal
163162
tar_path = Path(tmp_dir) / "malicious_test.tar.gz"
164163
extract_dir = Path(tmp_dir) / "extract"
165164
extract_dir.mkdir()
166-
165+
167166
# Create tar with malicious paths
168167
with tarfile.open(tar_path, 'w:gz') as tf:
169168
# Create a temporary file
170169
temp_file = Path(tmp_dir) / "temp.txt"
171170
temp_file.write_text("malicious content")
172-
171+
173172
# Add with malicious path (trying to write outside extraction directory)
174173
tf.add(temp_file, arcname="../../../etc/malicious.txt")
175-
174+
176175
# This should raise ValueError due to path traversal detection
177176
with self.assertRaises(ValueError) as context:
178177
extractall(str(tar_path), str(extract_dir))
179-
178+
180179
self.assertIn("unsafe path", str(context.exception).lower())
181-
180+
182181
def test_absolute_path_protection(self):
183182
"""Test protection against absolute paths in archives."""
184183
with tempfile.TemporaryDirectory() as tmp_dir:
185184
# Create zip with absolute path
186185
zip_path = Path(tmp_dir) / "absolute_path_test.zip"
187186
extract_dir = Path(tmp_dir) / "extract"
188187
extract_dir.mkdir()
189-
188+
190189
with zipfile.ZipFile(zip_path, 'w') as zf:
191190
# Try to use absolute path
192191
zf.writestr("/etc/passwd", "malicious content")
193-
192+
194193
# This should raise ValueError due to absolute path detection
195194
with self.assertRaises(ValueError) as context:
196195
extractall(str(zip_path), str(extract_dir))
197-
196+
198197
self.assertIn("unsafe path", str(context.exception).lower())
199198

200-
def test_malicious_symlink_protection(self):
201-
"""Test protection against malicious symlinks in tar archives."""
202-
with tempfile.TemporaryDirectory() as tmp_dir:
203-
# Create malicious tar file with symlink
204-
tar_path = Path(tmp_dir) / "malicious_symlink_test.tar.gz"
205-
extract_dir = Path(tmp_dir) / "extract"
206-
extract_dir.mkdir()
207-
208-
# Create tar with malicious symlink
209-
with tarfile.open(tar_path, 'w:gz') as tf:
210-
temp_file = Path(tmp_dir) / "normal.txt"
211-
temp_file.write_text("normal content")
212-
tf.add(temp_file, arcname="normal.txt")
213-
214-
symlink_info = tarfile.TarInfo(name="malicious_symlink.txt")
215-
symlink_info.type = tarfile.SYMTYPE
216-
symlink_info.linkname = "../../../etc/passwd"
217-
symlink_info.size = 0
218-
tf.addfile(symlink_info)
219-
220-
with self.assertRaises(ValueError) as context:
221-
extractall(str(tar_path), str(extract_dir))
222-
199+
def test_malicious_symlink_protection(self):
200+
"""Test protection against malicious symlinks in tar archives."""
201+
with tempfile.TemporaryDirectory() as tmp_dir:
202+
# Create malicious tar file with symlink
203+
tar_path = Path(tmp_dir) / "malicious_symlink_test.tar.gz"
204+
extract_dir = Path(tmp_dir) / "extract"
205+
extract_dir.mkdir()
206+
207+
# Create tar with malicious symlink
208+
with tarfile.open(tar_path, 'w:gz') as tf:
209+
temp_file = Path(tmp_dir) / "normal.txt"
210+
temp_file.write_text("normal content")
211+
tf.add(temp_file, arcname="normal.txt")
212+
213+
symlink_info = tarfile.TarInfo(name="malicious_symlink.txt")
214+
symlink_info.type = tarfile.SYMTYPE
215+
symlink_info.linkname = "../../../etc/passwd"
216+
symlink_info.size = 0
217+
tf.addfile(symlink_info)
218+
219+
with self.assertRaises(ValueError) as context:
220+
extractall(str(tar_path), str(extract_dir))
221+
223222
error_msg = str(context.exception).lower()
224223
self.assertTrue("unsafe path" in error_msg or "symlink" in error_msg)
225-
226-
def test_malicious_hardlink_protection(self):
227-
"""Test protection against malicious hard links in tar archives."""
228-
with tempfile.TemporaryDirectory() as tmp_dir:
229-
# Create malicious tar file with hard link
230-
tar_path = Path(tmp_dir) / "malicious_hardlink_test.tar.gz"
231-
extract_dir = Path(tmp_dir) / "extract"
232-
extract_dir.mkdir()
233-
234-
# Create tar with malicious hard link
235-
with tarfile.open(tar_path, 'w:gz') as tf:
236-
temp_file = Path(tmp_dir) / "normal.txt"
237-
temp_file.write_text("normal content")
238-
tf.add(temp_file, arcname="normal.txt")
239-
240-
hardlink_info = tarfile.TarInfo(name="malicious_hardlink.txt")
241-
hardlink_info.type = tarfile.LNKTYPE
242-
hardlink_info.linkname = "/etc/passwd"
243-
hardlink_info.size = 0
244-
tf.addfile(hardlink_info)
245-
246-
with self.assertRaises(ValueError) as context:
247-
extractall(str(tar_path), str(extract_dir))
248-
224+
225+
def test_malicious_hardlink_protection(self):
226+
"""Test protection against malicious hard links in tar archives."""
227+
with tempfile.TemporaryDirectory() as tmp_dir:
228+
# Create malicious tar file with hard link
229+
tar_path = Path(tmp_dir) / "malicious_hardlink_test.tar.gz"
230+
extract_dir = Path(tmp_dir) / "extract"
231+
extract_dir.mkdir()
232+
233+
# Create tar with malicious hard link
234+
with tarfile.open(tar_path, 'w:gz') as tf:
235+
temp_file = Path(tmp_dir) / "normal.txt"
236+
temp_file.write_text("normal content")
237+
tf.add(temp_file, arcname="normal.txt")
238+
239+
hardlink_info = tarfile.TarInfo(name="malicious_hardlink.txt")
240+
hardlink_info.type = tarfile.LNKTYPE
241+
hardlink_info.linkname = "/etc/passwd"
242+
hardlink_info.size = 0
243+
tf.addfile(hardlink_info)
244+
245+
with self.assertRaises(ValueError) as context:
246+
extractall(str(tar_path), str(extract_dir))
247+
249248
error_msg = str(context.exception).lower()
250249
self.assertTrue("unsafe path" in error_msg or "hardlink" in error_msg)
251250

0 commit comments

Comments
 (0)