Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Lib/tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2784,6 +2784,9 @@ def makelink_with_filter(self, tarinfo, targetpath,
"makelink_with_filter: if filter_function is not None, "
+ "extraction_root must also not be None")
try:
filter_function(
unfiltered.replace(name=tarinfo.name, deep=False),
extraction_root)
filtered = filter_function(unfiltered, extraction_root)
except _FILTER_ERRORS as cause:
raise LinkFallbackError(tarinfo, unfiltered.name) from cause
Expand Down
24 changes: 24 additions & 0 deletions Lib/test/test_tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4413,6 +4413,30 @@ def test_sneaky_hardlink_fallback(self):
self.expect_file("boom", symlink_to='../../link_here')
self.expect_file("c", symlink_to='b')

@symlink_test
def test_sneaky_hardlink_fallback_deep(self):
# (CVE-2026-11940)
with ArchiveMaker() as arc:
arc.add("a/b/s", symlink_to=os.path.join("..", "escape"))
arc.add("s", hardlink_to=os.path.join("a", "b", "s"))

with self.check_context(arc.open(), 'data'):
e = self.expect_exception(
tarfile.LinkFallbackError,
"link 's' would be extracted as a copy of "
+ "'a/b/s', which was rejected")
self.assertIsInstance(e.__cause__,
tarfile.LinkOutsideDestinationError)

for filter in 'tar', 'fully_trusted':
with self.subTest(filter), self.check_context(arc.open(), filter):
if not os_helper.can_symlink():
self.expect_file("a/")
self.expect_file("a/b/")
else:
self.expect_file("a/b/s", symlink_to=os.path.join('..', 'escape'))
self.expect_file("s", symlink_to=os.path.join('..', 'escape'))

@symlink_test
def test_exfiltration_via_symlink(self):
# (CVE-2025-4138)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed an vulnerability in the :mod:`tarfile` ``data`` and ``tar`` extraction
filters where crafted archives could create a symlink pointing outside the
destination directory. This was a bypass of :cve:`2025-4330`.
Loading