From c455bc907d7190b10956c5a809c5128af51eebec Mon Sep 17 00:00:00 2001 From: nuxsmin Date: Sat, 24 Dec 2016 19:43:28 +0100 Subject: [PATCH] * [FIX] Critical bugfix that prevents directory traversal in JS/CSS includes. Thanks to Jan Van for the notice --- css/css.php | 2 +- inc/SP/Html/Minify.class.php | 12 ++++++++---- inc/SP/Http/Request.class.php | 34 ++++++++++++++++++++++++++++++++++ js/js.php | 2 +- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/css/css.php b/css/css.php index 896aaff1..d5893e96 100644 --- a/css/css.php +++ b/css/css.php @@ -52,7 +52,7 @@ if (!$file) { $Minify = new Minify(); $Minify->setType(Minify::FILETYPE_CSS) - ->setBase(Init::$SERVERROOT . urldecode($base)) + ->setBase(urldecode($base), true) ->addFile(urldecode($file)) ->getMinified(); } \ No newline at end of file diff --git a/inc/SP/Html/Minify.class.php b/inc/SP/Html/Minify.class.php index d3ee3236..101efbd3 100644 --- a/inc/SP/Html/Minify.class.php +++ b/inc/SP/Html/Minify.class.php @@ -66,11 +66,12 @@ class Minify /** * @param string $base + * @param bool $checkPath * @return $this */ - public function setBase($base) + public function setBase($base, $checkPath = false) { - $this->base = $base; + $this->base = $checkPath === true ? Request::getSecureAppPath($base) : $base; return $this; } @@ -218,16 +219,19 @@ class Minify } else { $filePath = $this->base . DIRECTORY_SEPARATOR . $file; +// debugLog($this->base); +// debugLog($filePath); + if (file_exists($filePath)) { $this->files[] = array( 'type' => 'file', 'base' => $this->base, - 'name' => $file, + 'name' => Request::getSecureAppFile($file, $this->base), 'min' => $minify === true && $this->needsMinify($file), 'md5' => md5_file($filePath) ); } else { - error_log('File not found: ' . $filePath); + debugLog('File not found: ' . $filePath); } } diff --git a/inc/SP/Http/Request.class.php b/inc/SP/Http/Request.class.php index 957c4f67..c0c36626 100644 --- a/inc/SP/Http/Request.class.php +++ b/inc/SP/Http/Request.class.php @@ -218,4 +218,38 @@ class Request return count($params) > 0 ? '?' . implode('&', $params) : ''; } + + /** + * Devolver una ruta segura para + * + * @param $path + * @param null $base + * @return string + */ + public static function getSecureAppPath($path, $base = null) + { + if ($base === null) { + $base = Init::$SERVERROOT; + } + + $realPath = realpath($base . DIRECTORY_SEPARATOR . $path); + + if ($realPath === false || strpos($realPath, $base) !== 0) { + return ''; + } else { + return $realPath; + } + } + + /** + * Devuelve un nombre de archivo seguro + * + * @param $file + * @param null $base + * @return string + */ + public static function getSecureAppFile($file, $base = null) + { + return basename(self::getSecureAppPath($file, $base)); + } } \ No newline at end of file diff --git a/js/js.php b/js/js.php index 73cb7c0e..c0f015a4 100644 --- a/js/js.php +++ b/js/js.php @@ -67,7 +67,7 @@ if (!$file) { } elseif ($file && $base) { $Minify = new Minify(); $Minify->setType(Minify::FILETYPE_JS); - $Minify->setBase(\SP\Core\Init::$SERVERROOT . urldecode($base)); + $Minify->setBase(urldecode($base), true); $Minify->addFile(urldecode($file)); $Minify->getMinified(); } \ No newline at end of file