From 192c8c3b887aab34117b983c687934ca7c305209 Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Wed, 18 Mar 2026 21:43:29 +0100 Subject: [PATCH] fix IDOR private projects --- app/Http/Controllers/Api/V1/ProjectController.php | 2 +- .../Unit/Endpoint/Api/V1/ProjectEndpointTest.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/V1/ProjectController.php b/app/Http/Controllers/Api/V1/ProjectController.php index 060b836f..9827401e 100644 --- a/app/Http/Controllers/Api/V1/ProjectController.php +++ b/app/Http/Controllers/Api/V1/ProjectController.php @@ -78,7 +78,7 @@ class ProjectController extends Controller */ public function show(Organization $organization, Project $project): JsonResource { - $this->checkPermission($organization, 'projects:view', $project); + $this->checkPermission($organization, 'projects:view:all', $project); // Note: There is currently no need to check if a user is a member of the project, // since this is only relevant for users with the role "employee" and they can not access this endpoint. diff --git a/tests/Unit/Endpoint/Api/V1/ProjectEndpointTest.php b/tests/Unit/Endpoint/Api/V1/ProjectEndpointTest.php index d9312f8e..e0cb8e0b 100644 --- a/tests/Unit/Endpoint/Api/V1/ProjectEndpointTest.php +++ b/tests/Unit/Endpoint/Api/V1/ProjectEndpointTest.php @@ -281,6 +281,7 @@ class ProjectEndpointTest extends ApiEndpointTestAbstract // Arrange $data = $this->createUserWithPermission([ 'projects:view', + 'projects:view:all', ]); $project = Project::factory()->forOrganization($data->organization)->create(); Passport::actingAs($data->user); @@ -293,6 +294,20 @@ class ProjectEndpointTest extends ApiEndpointTestAbstract $response->assertJsonPath('data.id', $project->getKey()); } + public function test_show_endpoint_fails_if_employee_tries_to_access_private_project_that_they_are_not_a_member_of(): void + { + // Arrange + $data = $this->createUserWithRole(Role::Employee); + $privateProject = Project::factory()->forOrganization($data->organization)->isPrivate()->create(); + Passport::actingAs($data->user); + + // Act + $response = $this->getJson(route('api.v1.projects.show', [$data->organization->getKey(), $privateProject->getKey()])); + + // Assert + $response->assertForbidden(); + } + public function test_store_endpoint_fails_if_user_has_no_permission_to_create_projects(): void { // Arrange