From a5ed6a833d0f1457d061f16dfc5a5c1a42582c76 Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Wed, 20 Sep 2023 18:38:04 +0100 Subject: [PATCH 1/3] fix(1.x,suspend): suspended users can abuse avatar upload --- extensions/suspend/src/Access/UserPolicy.php | 7 +++++++ framework/core/src/User/Access/UserPolicy.php | 11 +++++++++++ .../core/src/User/Command/UploadAvatarHandler.php | 4 +--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/extensions/suspend/src/Access/UserPolicy.php b/extensions/suspend/src/Access/UserPolicy.php index 69823772cf..311bbbcf56 100644 --- a/extensions/suspend/src/Access/UserPolicy.php +++ b/extensions/suspend/src/Access/UserPolicy.php @@ -25,4 +25,11 @@ public function suspend(User $actor, User $user) return $this->deny(); } } + + public function uploadAvatar(User $actor, User $user) + { + if ($actor->suspended_until && $actor->suspended_until->isFuture()) { + return $this->deny(); + } + } } diff --git a/framework/core/src/User/Access/UserPolicy.php b/framework/core/src/User/Access/UserPolicy.php index 274c9aaa51..9b97da6edb 100644 --- a/framework/core/src/User/Access/UserPolicy.php +++ b/framework/core/src/User/Access/UserPolicy.php @@ -39,4 +39,15 @@ public function editCredentials(User $actor, User $user) return $this->allow(); } } + + public function uploadAvatar(User $actor, User $user) + { + if ($actor->id === $user->id) { + return $this->allow(); + } + + if ($actor->id !== $user->id) { + return $actor->can('edit', $user); + } + } } diff --git a/framework/core/src/User/Command/UploadAvatarHandler.php b/framework/core/src/User/Command/UploadAvatarHandler.php index ae88442304..b7bd39a2cd 100644 --- a/framework/core/src/User/Command/UploadAvatarHandler.php +++ b/framework/core/src/User/Command/UploadAvatarHandler.php @@ -68,9 +68,7 @@ public function handle(UploadAvatar $command) $user = $this->users->findOrFail($command->userId); - if ($actor->id !== $user->id) { - $actor->assertCan('edit', $user); - } + $actor->assertCan('uploadAvatar', $user); $this->validator->assertValid(['avatar' => $command->file]); From 23ea72f9593715bf3f2f02bae63d4615eeabb43f Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Wed, 20 Sep 2023 21:02:20 +0100 Subject: [PATCH 2/3] test: works as expected --- extensions/suspend/tests/fixtures/avatar.png | Bin 0 -> 45168 bytes .../api/users/UploadAvatarTest.php | 103 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 extensions/suspend/tests/fixtures/avatar.png create mode 100644 extensions/suspend/tests/integration/api/users/UploadAvatarTest.php diff --git a/extensions/suspend/tests/fixtures/avatar.png b/extensions/suspend/tests/fixtures/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..2d3bea75241c977c5a63fb8fee024b2019a2c8b8 GIT binary patch literal 45168 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 A4*&oF literal 0 HcmV?d00001 diff --git a/extensions/suspend/tests/integration/api/users/UploadAvatarTest.php b/extensions/suspend/tests/integration/api/users/UploadAvatarTest.php new file mode 100644 index 0000000000..d2b85c980e --- /dev/null +++ b/extensions/suspend/tests/integration/api/users/UploadAvatarTest.php @@ -0,0 +1,103 @@ +extension('flarum-suspend'); + + $this->prepareDatabase([ + 'users' => [ + ['id' => 1, 'username' => 'Muralf', 'email' => 'muralf@machine.local', 'is_email_confirmed' => 1], + $this->normalUser(), + ['id' => 3, 'username' => 'acme', 'email' => 'acme@machine.local', 'is_email_confirmed' => 1, 'suspended_until' => Carbon::now()->addDay(), 'suspend_message' => 'You have been suspended.', 'suspend_reason' => 'Suspended for acme reasons.'], + ['id' => 4, 'username' => 'acme4', 'email' => 'acme4@machine.local', 'is_email_confirmed' => 1], + ['id' => 5, 'username' => 'acme5', 'email' => 'acme5@machine.local', 'is_email_confirmed' => 1, 'suspended_until' => Carbon::now()->subDay(), 'suspend_message' => 'You have been suspended.', 'suspend_reason' => 'Suspended for acme reasons.'], + ], + 'groups' => [ + ['id' => 5, 'name_singular' => 'can_edit_users', 'name_plural' => 'can_edit_users', 'is_hidden' => 0] + ], + 'group_user' => [ + ['user_id' => 2, 'group_id' => 5] + ], + 'group_permission' => [ + ['permission' => 'user.edit', 'group_id' => 5], + ] + ]); + } + + /** + * @dataProvider allowedToUploadAvatar + * @test + */ + public function can_suspend_user_if_allowed(?int $authenticatedAs, int $targetUserId, string $message) + { + $response = $this->sendUploadAvatarRequest($authenticatedAs, $targetUserId); + + $this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents()); + } + + /** + * @dataProvider unallowedToUploadAvatar + * @test + */ + public function cannot_suspend_user_if_not_allowed(?int $authenticatedAs, int $targetUserId, string $message) + { + $response = $this->sendUploadAvatarRequest($authenticatedAs, $targetUserId); + + $this->assertEquals(403, $response->getStatusCode(), $response->getBody()->getContents()); + } + + public function allowedToUploadAvatar(): array + { + return [ + [1, 2, 'Admin can upload avatar for any user'], + [2, 3, 'User with permission can upload avatar for suspended user'], + [2, 2, 'User with permission can upload avatar for self'], + [2, 4, 'User with permission can upload avatar for other user'], + [1, 1, 'Admin can upload avatar for self'], + [5, 5, 'Suspended user can upload avatar for self if suspension expired'], + ]; + } + + public function unallowedToUploadAvatar(): array + { + return [ + [3, 3, 'Suspended user cannot upload avatar for self'], + [3, 2, 'Suspended user cannot upload avatar for other user'], + [4, 3, 'User without permission cannot upload avatar for suspended user'], + [4, 2, 'User without permission cannot upload avatar for other user'], + [5, 2, 'Suspended user cannot upload avatar for other user if suspension expired'], + ]; + } + + protected function sendUploadAvatarRequest(?int $authenticatedAs, int $targetUserId): ResponseInterface + { + return $this->send( + $this->request('POST', "/api/users/$targetUserId/avatar", [ + 'authenticatedAs' => $authenticatedAs, + ])->withHeader('Content-Type', 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW')->withUploadedFiles([ + 'avatar' => new UploadedFile(__DIR__ . '/../../../fixtures/avatar.png', 0, UPLOAD_ERR_OK, 'avatar.png', 'image/png') + ]) + ); + } +} From bdda995cd85ab96051e51c3d478736f282fbad96 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Wed, 20 Sep 2023 20:02:47 +0000 Subject: [PATCH 3/3] Apply fixes from StyleCI --- .../suspend/tests/integration/api/users/UploadAvatarTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/suspend/tests/integration/api/users/UploadAvatarTest.php b/extensions/suspend/tests/integration/api/users/UploadAvatarTest.php index d2b85c980e..7620c2de7a 100644 --- a/extensions/suspend/tests/integration/api/users/UploadAvatarTest.php +++ b/extensions/suspend/tests/integration/api/users/UploadAvatarTest.php @@ -96,7 +96,7 @@ protected function sendUploadAvatarRequest(?int $authenticatedAs, int $targetUse $this->request('POST', "/api/users/$targetUserId/avatar", [ 'authenticatedAs' => $authenticatedAs, ])->withHeader('Content-Type', 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW')->withUploadedFiles([ - 'avatar' => new UploadedFile(__DIR__ . '/../../../fixtures/avatar.png', 0, UPLOAD_ERR_OK, 'avatar.png', 'image/png') + 'avatar' => new UploadedFile(__DIR__.'/../../../fixtures/avatar.png', 0, UPLOAD_ERR_OK, 'avatar.png', 'image/png') ]) ); }