Skip to content

Commit 52110d7

Browse files
authored
Fix Path Traversal in multissltests.py
Fix of a Path Traversal vulnerability in a test script in multissltests.py
1 parent 9ee0214 commit 52110d7

File tree

1 file changed

+45
-20
lines changed

1 file changed

+45
-20
lines changed

Tools/ssl/multissltests.py

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -288,26 +288,51 @@ def _download_src(self):
288288
f.write(data)
289289

290290
def _unpack_src(self):
291-
"""Unpack tar.gz bundle"""
292-
# cleanup
293-
if os.path.isdir(self.build_dir):
294-
shutil.rmtree(self.build_dir)
295-
os.makedirs(self.build_dir)
296-
297-
tf = tarfile.open(self.src_file)
298-
name = self.build_template.format(self.version)
299-
base = name + '/'
300-
# force extraction into build dir
301-
members = tf.getmembers()
302-
for member in list(members):
303-
if member.name == name:
304-
members.remove(member)
305-
elif not member.name.startswith(base):
306-
raise ValueError(member.name, base)
307-
member.name = member.name[len(base):].lstrip('/')
308-
log.info("Unpacking files to {}".format(self.build_dir))
309-
tf.extractall(self.build_dir, members)
310-
291+
"""Unpack tar.gz bundle"""
292+
# cleanup
293+
if os.path.isdir(self.build_dir):
294+
shutil.rmtree(self.build_dir)
295+
os.makedirs(self.build_dir)
296+
297+
tf = tarfile.open(self.src_file)
298+
name = self.build_template.format(self.version)
299+
base = name + '/'
300+
# force extraction into build dir
301+
members = tf.getmembers()
302+
303+
log.info("Unpacking files to {}".format(self.build_dir))
304+
build_dir_real = os.path.realpath(self.build_dir)
305+
306+
for member in members:
307+
if member.name == name:
308+
continue
309+
elif not member.name.startswith(base):
310+
raise ValueError(member.name, base)
311+
312+
# Strip the base directory and normalize the path
313+
member.name = member.name[len(base):].lstrip('/')
314+
315+
# Security checks for safe extraction
316+
if member.islnk() or member.issym():
317+
log.warning("Skipping symbolic/hard link: {}".format(member.name))
318+
continue
319+
320+
# Normalize the member path
321+
normalized_path = os.path.normpath(member.name)
322+
323+
# Check for directory traversal attempts
324+
if normalized_path.startswith('/') or '..' in normalized_path.split(os.sep):
325+
log.warning("Skipping potentially malicious member: {}".format(member.name))
326+
continue
327+
328+
# Construct final path and validate it's within build directory
329+
final_path = os.path.realpath(os.path.join(self.build_dir, normalized_path))
330+
if not final_path.startswith(build_dir_real + os.sep) and final_path != build_dir_real:
331+
log.warning("Skipping member attempting directory traversal: {}".format(member.name))
332+
continue
333+
334+
# Safe extraction
335+
tf.extract(member, self.build_dir)
311336
def _build_src(self, config_args=()):
312337
"""Now build openssl"""
313338
log.info("Running build in {}".format(self.build_dir))

0 commit comments

Comments
 (0)