diff options
author | John Molakvoæ <skjnldsv@users.noreply.github.com> | 2021-12-07 12:12:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-07 12:12:40 +0100 |
commit | ee1fe51f88632c5a57a9ff2b1968a76cc81d2d18 (patch) | |
tree | 8fbe3ac1fa7a4161a9e7658f798a14c2216260d9 | |
parent | feb20080e8624923a4c5c94131f9263148fb66f6 (diff) | |
parent | 5223b0b6112defe682aafcddeda951b5461c95c8 (diff) | |
download | nextcloud-server-ee1fe51f88632c5a57a9ff2b1968a76cc81d2d18.tar.gz nextcloud-server-ee1fe51f88632c5a57a9ff2b1968a76cc81d2d18.zip |
Merge pull request #30114 from nextcloud/fix/sanitizeMtime
-rw-r--r-- | apps/dav/lib/Connector/Sabre/Node.php | 5 | ||||
-rw-r--r-- | apps/dav/tests/unit/Connector/Sabre/FileTest.php | 24 | ||||
-rw-r--r-- | apps/dav/tests/unit/Connector/Sabre/NodeTest.php | 48 |
3 files changed, 63 insertions, 14 deletions
diff --git a/apps/dav/lib/Connector/Sabre/Node.php b/apps/dav/lib/Connector/Sabre/Node.php index 7f7299296c6..0fc8a441277 100644 --- a/apps/dav/lib/Connector/Sabre/Node.php +++ b/apps/dav/lib/Connector/Sabre/Node.php @@ -412,6 +412,11 @@ abstract class Node implements \Sabre\DAV\INode { throw new \InvalidArgumentException('X-OC-MTime header must be an integer (unix timestamp).'); } + // Prevent writing invalid mtime (timezone-proof) + if ((int)$mtimeFromRequest <= 24 * 60 * 60) { + throw new \InvalidArgumentException('X-OC-MTime header must be a valid positive integer'); + } + return (int)$mtimeFromRequest; } } diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php index 304e8abed07..3e6a47d5854 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php @@ -361,28 +361,28 @@ class FileTest extends TestCase { 'expected result' => null ], "castable string (int)" => [ - 'HTTP_X_OC_MTIME' => "34", - 'expected result' => 34 + 'HTTP_X_OC_MTIME' => "987654321", + 'expected result' => 987654321 ], "castable string (float)" => [ - 'HTTP_X_OC_MTIME' => "34.56", - 'expected result' => 34 + 'HTTP_X_OC_MTIME' => "123456789.56", + 'expected result' => 123456789 ], "float" => [ - 'HTTP_X_OC_MTIME' => 34.56, - 'expected result' => 34 + 'HTTP_X_OC_MTIME' => 123456789.56, + 'expected result' => 123456789 ], "zero" => [ 'HTTP_X_OC_MTIME' => 0, - 'expected result' => 0 + 'expected result' => null ], "zero string" => [ 'HTTP_X_OC_MTIME' => "0", - 'expected result' => 0 + 'expected result' => null ], "negative zero string" => [ 'HTTP_X_OC_MTIME' => "-0", - 'expected result' => 0 + 'expected result' => null ], "string starting with number following by char" => [ 'HTTP_X_OC_MTIME' => "2345asdf", @@ -398,11 +398,11 @@ class FileTest extends TestCase { ], "negative int" => [ 'HTTP_X_OC_MTIME' => -34, - 'expected result' => -34 + 'expected result' => null ], "negative float" => [ 'HTTP_X_OC_MTIME' => -34.43, - 'expected result' => -34 + 'expected result' => null ], ]; } @@ -421,7 +421,6 @@ class FileTest extends TestCase { if ($resultMtime === null) { $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage("X-OC-MTime header must be an integer (unix timestamp)."); } $this->doPut($file, null, $request); @@ -447,7 +446,6 @@ class FileTest extends TestCase { if ($resultMtime === null) { $this->expectException(\Sabre\DAV\Exception::class); - $this->expectExceptionMessage("X-OC-MTime header must be an integer (unix timestamp)."); } $this->doPut($file.'-chunking-12345-2-0', null, $request); diff --git a/apps/dav/tests/unit/Connector/Sabre/NodeTest.php b/apps/dav/tests/unit/Connector/Sabre/NodeTest.php index 18ccd0fe690..00fd0ebd8aa 100644 --- a/apps/dav/tests/unit/Connector/Sabre/NodeTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/NodeTest.php @@ -164,8 +164,54 @@ class NodeTest extends \Test\TestCase { ->disableOriginalConstructor() ->getMock(); - $node = new \OCA\DAV\Connector\Sabre\File($view, $info); + $node = new \OCA\DAV\Connector\Sabre\File($view, $info); $this->invokePrivate($node, 'shareManager', [$shareManager]); $this->assertEquals($expected, $node->getSharePermissions($user)); } + + public function sanitizeMtimeProvider() { + return [ + [123456789, 123456789], + ['987654321', 987654321], + ]; + } + + /** + * @dataProvider sanitizeMtimeProvider + */ + public function testSanitizeMtime($mtime, $expected) { + $view = $this->getMockBuilder(View::class) + ->disableOriginalConstructor() + ->getMock(); + $info = $this->getMockBuilder(FileInfo::class) + ->disableOriginalConstructor() + ->getMock(); + + $node = new \OCA\DAV\Connector\Sabre\File($view, $info); + $result = $this->invokePrivate($node, 'sanitizeMtime', [$mtime]); + $this->assertEquals($expected, $result); + } + + public function invalidSanitizeMtimeProvider() { + return [ + [-1337], [0], ['abcdef'], ['-1337'], ['0'], [12321], [24 * 60 * 60 - 1] + ]; + } + + /** + * @dataProvider invalidSanitizeMtimeProvider + */ + public function testInvalidSanitizeMtime($mtime) { + $this->expectException(\InvalidArgumentException::class); + + $view = $this->getMockBuilder(View::class) + ->disableOriginalConstructor() + ->getMock(); + $info = $this->getMockBuilder(FileInfo::class) + ->disableOriginalConstructor() + ->getMock(); + + $node = new \OCA\DAV\Connector\Sabre\File($view, $info); + $result = $this->invokePrivate($node, 'sanitizeMtime', [$mtime]); + } } |