From c2c373e2557e7cd74e7a930ca39598941e03d2e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:50:58 +0000 Subject: [PATCH 1/2] Initial plan From 707a6d9deb441872ab7eba726771b0f1175f844d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:53:38 +0000 Subject: [PATCH 2/2] Add negative test cases for path-traversal protection in update.retrieve() Co-authored-by: rilma <14822065+rilma@users.noreply.github.com> --- tests/test_api.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index c5bc0e4..911b96c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -48,3 +48,39 @@ def test_retrieve(self, url: str, filename: str, is_tar: bool): file_count = len([f for f in pathlib.Path(tmpdir).iterdir() if f.is_file()]) self.assertGreater(file_count, 0) + + def _make_tarball_with_traversal(self, directory: str, filename: str, member_name: str) -> str: + """Create a tarball fixture whose sole member uses a path-traversal name.""" + tarball_path = str(pathlib.Path(directory) / filename) + inner_content = b"malicious content" + buf = io.BytesIO(inner_content) + buf.seek(0) + with tarfile.open(tarball_path, "w") as tar: + info = tarfile.TarInfo(name=member_name) + info.size = len(inner_content) + tar.addfile(info, buf) + return tarball_path + + def test_retrieve_path_traversal_raises(self): + """A tar member that escapes the target directory must raise ValueError.""" + with tempfile.TemporaryDirectory() as tmpdir: + fake_path = self._make_tarball_with_traversal( + tmpdir, "traversal.tar", "../malicious.txt" + ) + with patch( + "pyiri2016.api.update.wget.download", return_value=fake_path + ): + with self.assertRaises(ValueError): + update.retrieve("http://example.com", "traversal.tar", directory=tmpdir) + + def test_retrieve_absolute_path_in_tar_raises(self): + """A tar member with an absolute path that escapes the target directory must raise ValueError.""" + with tempfile.TemporaryDirectory() as tmpdir: + fake_path = self._make_tarball_with_traversal( + tmpdir, "absolute.tar", "/etc/passwd" + ) + with patch( + "pyiri2016.api.update.wget.download", return_value=fake_path + ): + with self.assertRaises(ValueError): + update.retrieve("http://example.com", "absolute.tar", directory=tmpdir)