From b6da5c32254162fa0752616479fb3d3c5297c1cf Mon Sep 17 00:00:00 2001 From: Wolfgang Popp Date: Tue, 2 Feb 2021 23:32:18 +0100 Subject: [PATCH] Fix out-of-path check for virtual relative symlink A symlink is out-of-path if it is an absolute path or goes "up" too many times. This checks how deep the filename is and whether the link points more levels up than the depth of the filename. --- Archive/Tar.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Archive/Tar.php b/Archive/Tar.php index 8a2d2db..ccbae6d 100644 --- a/Archive/Tar.php +++ b/Archive/Tar.php @@ -2124,7 +2124,25 @@ public function _extractList( } } } elseif ($v_header['typeflag'] == "2") { - if (strpos(realpath(dirname($v_header['link'])), realpath($p_path)) !== 0) { + $link_depth = 0; + foreach (explode("/", $v_header['filename']) as $dir) { + if ($dir === "..") { + $link_depth--; + } elseif ($dir !== "" && $dir !== "." ) { + $link_depth++; + } + } + foreach (explode("/", $v_header['link']) as $dir){ + if ($link_depth <= 0) { + break; + } + if ($dir === "..") { + $link_depth--; + } elseif ($dir !== "" && $dir !== ".") { + $link_depth++; + } + } + if (str_starts_with($v_header['link'], "/") or $link_depth <= 0) { $this->_error( 'Out-of-path file extraction {' . $v_header['filename'] . ' --> ' .