Skip to content

Commit a460e1f

Browse files
authored
Update utils.py
Signed-off-by: h3rrr <81402797+h3rrr@users.noreply.github.com>
1 parent d07a269 commit a460e1f

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

monai/apps/utils.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111

1212
from __future__ import annotations
1313

14-
import os
15-
import shutil
1614
import hashlib
1715
import json
1816
import logging
17+
import os
1918
import re
19+
import shutil
2020
import sys
2121
import tarfile
2222
import tempfile
@@ -80,6 +80,7 @@ def get_logger(
8080
logger = get_logger("monai.apps")
8181
__all__.append("logger")
8282

83+
8384
def _basename(p: PathLike) -> str:
8485
"""get the last part of the path (removing the trailing slash if it exists)"""
8586
sep = os.path.sep + (os.path.altsep or "") + "/ "
@@ -120,23 +121,25 @@ def update_to(self, b: int = 1, bsize: int = 1, tsize: int | None = None) -> Non
120121
logger.error(f"Download failed from {url} to {filepath}.")
121122
raise e
122123

124+
123125
def safe_extract_member(member, extract_to):
124126
"""Securely verify compressed package member paths to prevent path traversal attacks"""
125127
# Get member path (handle different compression formats)
126-
if hasattr(member, 'filename'):
128+
if hasattr(member, "filename"):
127129
member_path = member.filename # zipfile
128-
elif hasattr(member, 'name'):
130+
elif hasattr(member, "name"):
129131
member_path = member.name # tarfile
130132
else:
131133
member_path = str(member)
132134

133-
if hasattr(member, 'issym') and member.issym():
134-
raise ValueError(f"Unsafe path: symlink {member_path}")
135-
if hasattr(member, 'islnk') and member.islnk():
136-
raise ValueError(f"Unsafe path: hardlink {member_path}")
135+
if hasattr(member, "issym") and member.issym():
136+
raise ValueError(f"Symbolic link detected in archive: {member_path}")
137+
if hasattr(member, "islnk") and member.islnk():
138+
raise ValueError(f"Hard link detected in archive: {member_path}")
139+
137140
member_path = os.path.normpath(member_path)
138141

139-
if os.path.isabs(member_path) or '..' in member_path.split(os.sep):
142+
if os.path.isabs(member_path) or ".." in member_path.split(os.sep):
140143
raise ValueError(f"Unsafe path detected in archive: {member_path}")
141144

142145
full_path = os.path.join(extract_to, member_path)
@@ -150,6 +153,7 @@ def safe_extract_member(member, extract_to):
150153

151154
return full_path
152155

156+
153157
def check_hash(filepath: PathLike, val: str | None = None, hash_type: str = "md5") -> bool:
154158
"""
155159
Verify hash signature of specified file.
@@ -315,19 +319,19 @@ def extractall(
315319
logger.info(f"Writing into directory: {output_dir}.")
316320
_file_type = file_type.lower().strip()
317321
if filepath.name.endswith("zip") or _file_type == "zip":
318-
with zipfile.ZipFile(filepath, 'r') as zip_file:
322+
with zipfile.ZipFile(filepath, "r") as zip_file:
319323
for member in zip_file.infolist():
320324
safe_path = safe_extract_member(member, output_dir)
321325
if member.is_dir():
322326
continue
323327

324328
os.makedirs(os.path.dirname(safe_path), exist_ok=True)
325329
with zip_file.open(member) as source:
326-
with open(safe_path, 'wb') as target:
330+
with open(safe_path, "wb") as target:
327331
shutil.copyfileobj(source, target)
328332
return
329333
if filepath.name.endswith("tar") or filepath.name.endswith("tar.gz") or "tar" in _file_type:
330-
with tarfile.open(filepath, 'r') as tar_file:
334+
with tarfile.open(filepath, "r") as tar_file:
331335
for member in tar_file.getmembers():
332336
safe_path = safe_extract_member(member, output_dir)
333337
if not member.isfile():
@@ -337,7 +341,7 @@ def extractall(
337341
source = tar_file.extractfile(member)
338342
if source is not None:
339343
with source:
340-
with open(safe_path, 'wb') as target:
344+
with open(safe_path, "wb") as target:
341345
shutil.copyfileobj(source, target)
342346
return
343347
raise NotImplementedError(

0 commit comments

Comments
 (0)