| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2801,7 +2801,11 @@ def makelink_with_filter(self, tarinfo, targetpath, | |||
| 2801 | 2801 | if os.path.lexists(targetpath): | |
| 2802 | 2802 | # Avoid FileExistsError on following os.link. | |
| 2803 | 2803 | os.unlink(targetpath) | |
| 2804 | - os.link(tarinfo._link_target, targetpath) | ||
| 2804 | + # Resolve the target so the hard link points to the file | ||
| 2805 | + # itself. Otherwise os.link() may duplicate a symlink to a | ||
| 2806 | + # shallower location, where its relative target escapes the | ||
| 2807 | + # destination directory. (CVE-2026-82049) | ||
| 2808 | + os.link(os.path.realpath(tarinfo._link_target), targetpath) | ||
| 2805 | 2809 | return | |
| 2806 | 2810 | except symlink_exception: | |
| 2807 | 2811 | keyerror_to_extracterror = True | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4485,6 +4485,24 @@ def test_sneaky_hardlink_fallback_deep(self): | |||
| 4485 | 4485 | self.expect_file("a/b/s", symlink_to=os.path.join('..', 'escape')) | |
| 4486 | 4486 | self.expect_file("s", symlink_to=os.path.join('..', 'escape')) | |
| 4487 | 4487 | ||
| 4488 | + @symlink_test | ||
| 4489 | + @os_helper.skip_unless_hardlink | ||
| 4490 | + def test_sneaky_hardlink_relocation(self): | ||
| 4491 | + with ArchiveMaker() as arc: | ||
| 4492 | + arc.add("a/escape", content="decoy") | ||
| 4493 | + arc.add("a/b/s", symlink_to=os.path.join("..", "escape")) | ||
| 4494 | + arc.add("s", hardlink_to=os.path.join("a", "b", "s")) | ||
| 4495 | + | ||
| 4496 | + for filter in 'data', 'tar': | ||
| 4497 | + with self.subTest(filter), self.check_context(arc.open(), filter): | ||
| 4498 | + self.expect_file("a/escape", content="decoy") | ||
| 4499 | + if os_helper.can_symlink(): | ||
| 4500 | + self.expect_file("a/b/s", symlink_to=os.path.join('..', 'escape')) | ||
| 4501 | + else: | ||
| 4502 | + self.expect_file("a/b/s", content="decoy") | ||
| 4503 | + self.expect_file("s", content="decoy") | ||
| 4504 | + self.assertFalse((self.destdir / "s").is_symlink()) | ||
| 4505 | + | ||
| 4488 | 4506 | @symlink_test | |
| 4489 | 4507 | def test_exfiltration_via_symlink(self): | |
| 4490 | 4508 | # (CVE-2025-4138) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments