Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
# Patching CVE-2007-4559

Hi, we are security researchers from the Advanced Research Center at
[Trellix](https://www.trellix.com). We have began a campaign to patch a
widespread bug named CVE-2007-4559. CVE-2007-4559 is a 15 year old bug
in the Python tarfile package. By using extract() or extractall() on a
tarfile object without sanitizing input, a maliciously crafted .tar file
could perform a directory path traversal attack. We found at least one
unsantized extractall() in your codebase and are providing a patch for
you via pull request. The patch essentially checks to see if all tarfile
members will be extracted safely and throws an exception otherwise. We
encourage you to use this patch or your own solution to secure against
CVE-2007-4559. Further technical information about the vulnerability can
be found in this
[blog](https://www.trellix.com/en-us/about/newsroom/stories/research/tarfile-exploiting-the-world.html).

If you have further questions you may contact us through this projects
lead researcher [Kasimir Schulz](mailto:[email protected]).
  • Loading branch information
TrellixVulnTeam authored Oct 11, 2022
1 parent b2a831b commit c757223
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
21 changes: 20 additions & 1 deletion dpgen/auto_test/lib/RemoteJob.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,26 @@ def _get_files(self,
cwd = os.getcwd()
os.chdir(self.local_root)
with tarfile.open(of, "r:gz") as tar:
tar.extractall()
def is_within_directory(directory, target):

abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)

prefix = os.path.commonprefix([abs_directory, abs_target])

return prefix == abs_directory

def safe_extract(tar, path=".", members=None, *, numeric_owner=False):

for member in tar.getmembers():
member_path = os.path.join(path, member.name)
if not is_within_directory(path, member_path):
raise Exception("Attempted Path Traversal in Tar File")

tar.extractall(path, members, numeric_owner=numeric_owner)


safe_extract(tar)
os.chdir(cwd)
# cleanup
os.remove(to_f)
Expand Down
21 changes: 20 additions & 1 deletion dpgen/dispatcher/SSHContext.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,26 @@ def _get_files(self,
cwd = os.getcwd()
os.chdir(self.local_root)
with tarfile.open(of, "r:gz") as tar:
tar.extractall()
def is_within_directory(directory, target):

abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)

prefix = os.path.commonprefix([abs_directory, abs_target])

return prefix == abs_directory

def safe_extract(tar, path=".", members=None, *, numeric_owner=False):

for member in tar.getmembers():
member_path = os.path.join(path, member.name)
if not is_within_directory(path, member_path):
raise Exception("Attempted Path Traversal in Tar File")

tar.extractall(path, members, numeric_owner=numeric_owner)


safe_extract(tar)
os.chdir(cwd)
# cleanup
os.remove(to_f)
Expand Down
21 changes: 20 additions & 1 deletion dpgen/remote/RemoteJob.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,26 @@ def _get_files(self,
cwd = os.getcwd()
os.chdir(self.local_root)
with tarfile.open(of, "r:gz") as tar:
tar.extractall()
def is_within_directory(directory, target):

abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)

prefix = os.path.commonprefix([abs_directory, abs_target])

return prefix == abs_directory

def safe_extract(tar, path=".", members=None, *, numeric_owner=False):

for member in tar.getmembers():
member_path = os.path.join(path, member.name)
if not is_within_directory(path, member_path):
raise Exception("Attempted Path Traversal in Tar File")

tar.extractall(path, members, numeric_owner=numeric_owner)


safe_extract(tar)
os.chdir(cwd)
# cleanup
os.remove(to_f)
Expand Down

0 comments on commit c757223

Please sign in to comment.