diff --git a/backend/Services/Storage/Filesystem.php b/backend/Services/Storage/Filesystem.php index 26720acf..fe3807ff 100644 --- a/backend/Services/Storage/Filesystem.php +++ b/backend/Services/Storage/Filesystem.php @@ -241,6 +241,7 @@ private function applyPathPrefix(string $path): string ) { $path = $this->separator; } + return $this->joinPaths($this->getPathPrefix(), $path); } @@ -266,6 +267,9 @@ private function addSeparators(string $dir): string private function joinPaths(string $path1, string $path2): string { + $path1 = $this->escapeDots($path1); + $path2 = $this->escapeDots($path2); + if (! $path2 || ! trim($path2, $this->separator)) { return $this->addSeparators($path1); } @@ -295,4 +299,14 @@ private function getBaseName(string $path): string return (string) array_pop($tmp); } + + private function escapeDots(string $path): string + { + $path = preg_replace('/\\\+\.{2,}/', '', $path); + $path = preg_replace('/\.{2,}\\\+/', '', $path); + $path = preg_replace('/\/+\.{2,}/', '', $path); + $path = preg_replace('/\.{2,}\/+/', '', $path); + + return $path; + } } diff --git a/tests/backend/Unit/FilesystemTest.php b/tests/backend/Unit/FilesystemTest.php index 97a1568d..02ff4b2f 100644 --- a/tests/backend/Unit/FilesystemTest.php +++ b/tests/backend/Unit/FilesystemTest.php @@ -461,6 +461,18 @@ public function testApplyPathPrefix() $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['..'])); $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['../'])); $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['/sub/../../'])); + $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['..\\'])); + $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['..\\\\'])); + $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['..\\..\\'])); + $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['\\\\..'])); + $this->assertEquals('/john/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['\\..\\..'])); + $this->assertEquals('/john/\\.', $this->invokeMethod($this->storage, 'applyPathPrefix', ['\\.\\...'])); + $this->assertEquals('/john/\\.', $this->invokeMethod($this->storage, 'applyPathPrefix', ['\\.\\....'])); + $this->assertEquals('/john/.\\.', $this->invokeMethod($this->storage, 'applyPathPrefix', ['.\\.\\...'])); + $this->assertEquals('/john/.', $this->invokeMethod($this->storage, 'applyPathPrefix', ['..\\.\\...'])); + $this->assertEquals('/john/.', $this->invokeMethod($this->storage, 'applyPathPrefix', ['..\\.\\...'])); + $this->assertEquals('/john/.', $this->invokeMethod($this->storage, 'applyPathPrefix', ['..\\.\\......'])); + $this->assertEquals('/john/.\\', $this->invokeMethod($this->storage, 'applyPathPrefix', ['...\\.\\......\\'])); } public function testStripPathPrefix()