From 9511bda44d7914c9849bff11ef08048d41b9af05 Mon Sep 17 00:00:00 2001 From: LouisGac Date: Fri, 22 Dec 2017 17:01:22 +0100 Subject: [PATCH] Dev: ported security fix Dev: [Security] Possible to edit file outside of template directory from template editor (found and reported by Robin Peraglie from RIPS Technologies www.ripstech.com ) --- application/helpers/common_helper.php | 20 ++++++++++++++++++++ application/models/TemplateManifest.php | 9 ++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index 7ae630215d7..5147ad0c117 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -4961,3 +4961,23 @@ function regenerateCSRFToken() $cookie->expire = time() - 3600; Yii::app()->request->cookies['YII_CSRF_TOKEN'] = $cookie; } + +/** +* A function to remove ../ or ./ from paths to prevent directory traversal +* +* @param mixed $path +*/ +function get_absolute_path($path) { + $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); + $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); + $absolutes = array(); + foreach ($parts as $part) { + if ('.' == $part) continue; + if ('..' == $part) { + array_pop($absolutes); + } else { + $absolutes[] = $part; + } + } + return implode(DIRECTORY_SEPARATOR, $absolutes); +} diff --git a/application/models/TemplateManifest.php b/application/models/TemplateManifest.php index c649c43b788..021e3891578 100755 --- a/application/models/TemplateManifest.php +++ b/application/models/TemplateManifest.php @@ -561,7 +561,14 @@ private function readManifest() if (file_exists(realpath($this->xmlFile))) { $bOldEntityLoaderState = libxml_disable_entity_loader(true); // @see: http://phpsecurity.readthedocs.io/en/latest/Injection-Attacks.html#xml-external-entity-injection $sXMLConfigFile = file_get_contents(realpath($this->xmlFile)); // @see: Now that entity loader is disabled, we can't use simplexml_load_file; so we must read the file with file_get_contents and convert it as a string - $this->config = simplexml_load_string($sXMLConfigFile); // Using PHP >= 5.4 then no need to decode encode + need attributes : then other function if needed :https://secure.php.net/manual/en/book.simplexml.php#108688 for example + $oXMLConfig = simplexml_load_string($sXMLConfigFile); + + + foreach($oXMLConfig->config->xpath("//file") as $oFileName){ + $oFileName[0] = get_absolute_path( $oFileName[0]); + } + + $this->config = $oXMLConfig; // Using PHP >= 5.4 then no need to decode encode + need attributes : then other function if needed :https://secure.php.net/manual/en/book.simplexml.php#108688 for example libxml_disable_entity_loader($bOldEntityLoaderState); // Put back entity loader to its original state, to avoid contagion to other applications on the server } else { throw new Exception(" Error: Can't find a manifest for $this->sTemplateName in ' $this->path ' ");