diff --git a/CHANGELOG.md b/CHANGELOG.md index 78e8407..3b9d037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Upcoming... +## 7.4.4 - 2020-07-28 [Security] + +* This version patches a security vulnerability #116 please upgrade + ## 7.4.3 - 2020-07-18 * disabling axios response auto-transformation when editing content, fixes #110 diff --git a/backend/Services/Storage/Filesystem.php b/backend/Services/Storage/Filesystem.php index 5b15350..d27b841 100644 --- a/backend/Services/Storage/Filesystem.php +++ b/backend/Services/Storage/Filesystem.php @@ -234,6 +234,9 @@ class Filesystem implements Service private function applyPathPrefix(string $path): string { + if (strpos($path, '..') !== false) { + $path = "/"; + } return $this->joinPaths($this->getPathPrefix(), $path); } diff --git a/dist/index.php b/dist/index.php index 6a546a2..6d322ca 100644 --- a/dist/index.php +++ b/dist/index.php @@ -39,7 +39,7 @@ if (! defined('APP_PUBLIC_PATH')) { } define('APP_PUBLIC_DIR', __DIR__); -define('APP_VERSION', '7.4.3'); +define('APP_VERSION', '7.4.4'); use Filegator\App; use Filegator\Config\Config; diff --git a/docs/install.md b/docs/install.md index 7328e1b..91ae1fb 100644 --- a/docs/install.md +++ b/docs/install.md @@ -9,7 +9,7 @@ currentMenu: install ## Download precompiled build Precompiled build is created for non-developers. In this version, the frontend (html, css and javascript) is compiled for you and the source code is removed so the final archive contains only minimum files. -- Download: [v7.4.3](https://github.com/filegator/static/raw/master/builds/filegator_v7.4.3.zip) +- Download: [v7.4.4](https://github.com/filegator/static/raw/master/builds/filegator_v7.4.4.zip) - Unzip files and upload them to your PHP server - Make sure your webserver can read and write to `filegator/repository/` and `filegator/private/` folders - Set the website document root to `filegator/dist/` directory. This is also known as 'public' folder @@ -26,8 +26,8 @@ apt update apt install -y wget unzip php apache2 libapache2-mod-php php-zip cd /var/www/ -wget https://github.com/filegator/static/raw/master/builds/filegator_v7.4.3.zip -unzip filegator_v7.4.3.zip && rm filegator_v7.4.3.zip +wget https://github.com/filegator/static/raw/master/builds/filegator_v7.4.4.zip +unzip filegator_v7.4.4.zip && rm filegator_v7.4.4.zip chown -R www-data:www-data filegator/ chmod -R 775 filegator/ diff --git a/tests/backend/Unit/FilesystemTest.php b/tests/backend/Unit/FilesystemTest.php index 6df7553..0418b34 100644 --- a/tests/backend/Unit/FilesystemTest.php +++ b/tests/backend/Unit/FilesystemTest.php @@ -401,6 +401,9 @@ class FilesystemTest extends TestCase $this->assertEquals('/john/test', $this->invokeMethod($this->storage, 'applyPathPrefix', ['/test'])); $this->assertEquals('/john/test.txt', $this->invokeMethod($this->storage, 'applyPathPrefix', ['test.txt'])); $this->assertEquals('/john/test.txt/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['test.txt/'])); + // no escaping path to upper dir + $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['/..'])); + $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['/sub/../../'])); } public function testStripPathPrefix() @@ -770,4 +773,49 @@ class FilesystemTest extends TestCase $this->assertDirectoryExists(TEST_REPOSITORY.'/test2/test1/'); } + + public function testCannotGoUpTheHomeDirUsingPathFiddle() + { + $this->storage->createFile('/', 'hidden.txt'); + $this->storage->createDir('/', 'johnsub'); + $this->storage->createFile('/johnsub', 'john.txt'); + $this->storage->setPathPrefix('/johnsub'); + + $ret = $this->storage->getDirectoryCollection('/'); + $ret->resetTimestamps(-1); + $this->assertJsonStringEqualsJsonString(json_encode([ + 'location' => '/', + 'files' => [ + 0 => [ + 'type' => 'file', + 'path' => '/john.txt', + 'name' => 'john.txt', + 'size' => 0, + 'time' => -1, + ], + ], + ]), json_encode($ret)); + + $ret = $this->storage->getDirectoryCollection('/..'); + $ret->resetTimestamps(-1); + $this->assertJsonStringEqualsJsonString(json_encode([ + 'location' => '/..', + 'files' => [ + 0 => [ + 'type' => 'back', + 'path' => '/', + 'name' => '..', + 'size' => 0, + 'time' => -1, + ], + 1 => [ + 'type' => 'file', + 'path' => '/john.txt', + 'name' => 'john.txt', + 'size' => 0, + 'time' => -1, + ], + ], + ]), json_encode($ret)); + } }