mirror of
https://github.com/clearml/clearml
synced 2025-06-25 09:36:04 +00:00
Fix potential path traversal on file download (CVE-2024-24591)
This commit is contained in:
parent
1b77e08ec8
commit
831c1394da
@ -29,6 +29,7 @@ from ..storage.util import sha256sum, is_windows, md5text, format_size
|
|||||||
from ..utilities.matching import matches_any_wildcard
|
from ..utilities.matching import matches_any_wildcard
|
||||||
from ..utilities.parallel import ParallelZipper
|
from ..utilities.parallel import ParallelZipper
|
||||||
from ..utilities.version import Version
|
from ..utilities.version import Version
|
||||||
|
from ..utilities.files import is_path_traversal
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from pathlib import Path as _Path # noqa
|
from pathlib import Path as _Path # noqa
|
||||||
@ -1856,6 +1857,12 @@ class Dataset(object):
|
|||||||
for ds in datasets:
|
for ds in datasets:
|
||||||
base_folder = Path(ds._get_dataset_files())
|
base_folder = Path(ds._get_dataset_files())
|
||||||
files = [f.relative_path for f in ds.file_entries if f.parent_dataset_id == ds.id]
|
files = [f.relative_path for f in ds.file_entries if f.parent_dataset_id == ds.id]
|
||||||
|
files = [
|
||||||
|
os.path.basename(file)
|
||||||
|
if is_path_traversal(base_folder, file) or is_path_traversal(temp_folder, file)
|
||||||
|
else file
|
||||||
|
for file in files
|
||||||
|
]
|
||||||
pool.map(
|
pool.map(
|
||||||
lambda x:
|
lambda x:
|
||||||
(temp_folder / x).parent.mkdir(parents=True, exist_ok=True) or
|
(temp_folder / x).parent.mkdir(parents=True, exist_ok=True) or
|
||||||
@ -2326,12 +2333,24 @@ class Dataset(object):
|
|||||||
link.size = Path(target_path).stat().st_size
|
link.size = Path(target_path).stat().st_size
|
||||||
if not max_workers:
|
if not max_workers:
|
||||||
for relative_path, link in links.items():
|
for relative_path, link in links.items():
|
||||||
|
if not is_path_traversal(target_folder, relative_path):
|
||||||
target_path = os.path.join(target_folder, relative_path)
|
target_path = os.path.join(target_folder, relative_path)
|
||||||
|
else:
|
||||||
|
LoggerRoot.get_base_logger().warning(
|
||||||
|
"Ignoring relative path `{}`: it must not traverse directories".format(relative_path)
|
||||||
|
)
|
||||||
|
target_path = os.path.join(target_folder, os.path.basename(relative_path))
|
||||||
_download_link(link, target_path)
|
_download_link(link, target_path)
|
||||||
else:
|
else:
|
||||||
with ThreadPoolExecutor(max_workers=max_workers) as pool:
|
with ThreadPoolExecutor(max_workers=max_workers) as pool:
|
||||||
for relative_path, link in links.items():
|
for relative_path, link in links.items():
|
||||||
|
if not is_path_traversal(target_folder, relative_path):
|
||||||
target_path = os.path.join(target_folder, relative_path)
|
target_path = os.path.join(target_folder, relative_path)
|
||||||
|
else:
|
||||||
|
LoggerRoot.get_base_logger().warning(
|
||||||
|
"Ignoring relative path `{}`: it must not traverse directories".format(relative_path)
|
||||||
|
)
|
||||||
|
target_path = os.path.join(target_folder, os.path.basename(relative_path))
|
||||||
pool.submit(_download_link, link, target_path)
|
pool.submit(_download_link, link, target_path)
|
||||||
|
|
||||||
def _extract_dataset_archive(
|
def _extract_dataset_archive(
|
||||||
|
@ -20,3 +20,15 @@ def get_filename_max_length(dir_path):
|
|||||||
print(err)
|
print(err)
|
||||||
|
|
||||||
return 255 # Common filesystems like NTFS, EXT4 and HFS+ limited with 255
|
return 255 # Common filesystems like NTFS, EXT4 and HFS+ limited with 255
|
||||||
|
|
||||||
|
|
||||||
|
def is_path_traversal(target_folder, relative_path):
|
||||||
|
try:
|
||||||
|
target_folder = pathlib2.Path(target_folder)
|
||||||
|
relative_path = pathlib2.Path(relative_path)
|
||||||
|
# returns the relative path starting from the target_folder,
|
||||||
|
# or raise an ValueError if a directory traversal attack is tried
|
||||||
|
target_folder.joinpath(relative_path).resolve().relative_to(target_folder.resolve())
|
||||||
|
return False
|
||||||
|
except ValueError:
|
||||||
|
return True
|
||||||
|
Loading…
Reference in New Issue
Block a user