Restrict remote archive extraction to safe members
This commit is contained in:
parent
df83ebc834
commit
c02815b0c1
2 changed files with 34 additions and 1 deletions
|
|
@ -197,7 +197,9 @@ class LargeFileBase(ABC):
|
|||
)
|
||||
|
||||
logger.info(f"Decompressing {self._local_name}")
|
||||
shutil.unpack_archive(str(tmp_file_archive), tmp, COMPRESSION_ALGORITHM)
|
||||
shutil.unpack_archive(
|
||||
str(tmp_file_archive), tmp, COMPRESSION_ALGORITHM, filter="data"
|
||||
)
|
||||
shutil.move(str(local_root_path / self._local_name), str(destination))
|
||||
else:
|
||||
logger.info(f"File {self._local_name} found in cache")
|
||||
|
|
|
|||
31
tests/large_file/test_archive_extraction.py
Normal file
31
tests/large_file/test_archive_extraction.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import io
|
||||
import tarfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from great_ai.large_file import LargeFileS3
|
||||
|
||||
|
||||
def test_remote_archive_cannot_escape_cache(tmp_path: Path) -> None:
|
||||
backend = MagicMock()
|
||||
backend.list_objects_v2.return_value = {"Contents": [{"Key": "model/0"}]}
|
||||
sentinel = tmp_path / "escaped"
|
||||
|
||||
def download(
|
||||
self: LargeFileS3, remote_path: str, local_path: Path, hide_progress: bool
|
||||
) -> None:
|
||||
with tarfile.open(local_path, "w:gz") as archive:
|
||||
member = tarfile.TarInfo("../escaped")
|
||||
member.size = 7
|
||||
archive.addfile(member, io.BytesIO(b"payload"))
|
||||
|
||||
with (
|
||||
patch.object(LargeFileS3, "cache_path", tmp_path / "cache"),
|
||||
patch.object(LargeFileS3, "_client", backend),
|
||||
patch.object(LargeFileS3, "_download", download),
|
||||
patch("tempfile.tempdir", str(tmp_path)),
|
||||
):
|
||||
with pytest.raises(tarfile.OutsideDestinationError):
|
||||
LargeFileS3("model").get()
|
||||
assert not sentinel.exists()
|
||||
Loading…
Reference in a new issue