From dfa49f12083ff958f713e54c7d77f3c491f35405 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Thu, 12 Dec 2013 14:54:20 +0100 Subject: [PATCH] Fixed #36. Potential security risk where relative paths would take a path outside of the defined root. --- src/Flysystem/Util.php | 19 ++++++++++++++++++- tests/FilesystemTests.php | 6 +++--- tests/UtilTests.php | 25 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/Flysystem/Util.php b/src/Flysystem/Util.php index 7776e75f9..c1068bb2a 100644 --- a/src/Flysystem/Util.php +++ b/src/Flysystem/Util.php @@ -77,7 +77,24 @@ public static function map(array $object, array $map) */ public static function normalizePath($path, $separator = '\\/') { - return ltrim($path, $separator); + // Remove any kind of funky unicode whitespace + $normalized = preg_replace('#\p{C}+|^\./#u', '', $path); + + // Path remove self referring paths ("/./"). + $normalized = preg_replace('#/\.(?=/)|^\./|\./$#', '', $normalized); + + // Regex for resolving relative paths + $regex = '#\/*[^/\.]+/\.\.#Uu'; + + while (preg_match($regex, $normalized)) { + $normalized = preg_replace($regex, '', $normalized); + } + + if (preg_match('#/\.{2}|\.{2}/#', $normalized)) { + throw new LogicException('Path is outside of the defined root, path: [' . $path . '], resolved: [' . $normalized . ']'); + } + + return trim($normalized, $separator); } /** diff --git a/tests/FilesystemTests.php b/tests/FilesystemTests.php index 849f7ea6e..c938693c6 100644 --- a/tests/FilesystemTests.php +++ b/tests/FilesystemTests.php @@ -164,12 +164,12 @@ public function testPutFail() } /** - * @dataProvider filesystemProvider * @expectedException \Flysystem\FileExistsException */ - public function testFileExists($filesystem) + public function testFileExists() { - $filesystem->write('../FilesystemTests.php', 'something'); + $filesystem = new Filesystem(new Adapter\Local(__DIR__)); + $filesystem->write('FilesystemTests.php', 'something'); } /** diff --git a/tests/UtilTests.php b/tests/UtilTests.php index 05b83179e..0b7f36ffb 100644 --- a/tests/UtilTests.php +++ b/tests/UtilTests.php @@ -69,4 +69,29 @@ public function testInvalidValueEnsureConfig() { Util::ensureConfig(false); } + + /** + * @expectedException LogicException + */ + public function testOutsideRootPath() + { + Util::normalizePath('something/../../../hehe'); + } + + public function pathProvider() + { + return array( + array('/dirname/', 'dirname'), + array('dirname/..', ''), + ); + } + + /** + * @dataProvider pathProvider + */ + public function testNormalizePath($input, $expected) + { + $result = Util::normalizePath($input); + $this->assertEquals($expected, $result); + } } \ No newline at end of file