diff --git a/src/Core/Path.php b/src/Core/Path.php index ac19475ba..891dc3754 100644 --- a/src/Core/Path.php +++ b/src/Core/Path.php @@ -34,7 +34,7 @@ class Path $fullPath = static::normalise(implode(DIRECTORY_SEPARATOR, $parts)); // Protect against directory traversal vulnerability (OTG-AUTHZ-001) - if (strpos($fullPath ?? '', '..') !== false) { + if ($fullPath === '..' || str_ends_with($fullPath, '/..') || str_contains($fullPath, '../')) { throw new InvalidArgumentException('Can not collapse relative folders'); } diff --git a/tests/php/Core/PathTest.php b/tests/php/Core/PathTest.php index 02580de74..10dff0e8d 100644 --- a/tests/php/Core/PathTest.php +++ b/tests/php/Core/PathTest.php @@ -48,6 +48,8 @@ class PathTest extends SapphireTest [['\\', '', '/root', '/', ' ', '/', '\\'], '/root'], // join blocks of paths [['/root/dir', 'another/path\\to/join'], '/root/dir/another/path/to/join'], + // Double dot is fine if it's not attempting directory traversal + [['/root/my..name/', 'another/path\\to/join'], '/root/my..name/another/path/to/join'], ]; // Rewrite tests for other filesystems (output arg only) @@ -79,6 +81,8 @@ class PathTest extends SapphireTest [['/base', '../passwd'], 'Can not collapse relative folders'], [['/base/../', 'passwd/path'], 'Can not collapse relative folders'], [['../', 'passwd/path'], 'Can not collapse relative folders'], + [['..', 'passwd/path'], 'Can not collapse relative folders'], + [['base/..', 'passwd/path'], 'Can not collapse relative folders'], ]; }