diff --git a/apps/api/plane/app/views/project/invite.py b/apps/api/plane/app/views/project/invite.py index 0cf1356461..df5767c4fb 100644 --- a/apps/api/plane/app/views/project/invite.py +++ b/apps/api/plane/app/views/project/invite.py @@ -52,11 +52,10 @@ class ProjectInvitationsViewset(BaseViewSet): .select_related("workspace", "workspace__owner") ) - # GHSA-r68c-48rr-m67f: project invitations expose invitee email + raw token - # and allow deletion, so every action must be restricted to project admins - # (mirroring create). Without these, the default list/retrieve/destroy - # inherited only IsAuthenticated, letting any workspace user read/delete - # another project's invitations. + # Project invitations expose the invitee email and the raw token, and can be + # deleted, so list/retrieve/destroy must be admin-only like create. Without + # these decorators they inherit only IsAuthenticated, letting any workspace + # user read or delete another project's invitations. @allow_permission([ROLE.ADMIN]) def list(self, request, slug, project_id): return super().list(request) @@ -167,7 +166,7 @@ class UserProjectInvitationsViewset(BaseViewSet): # Use the workspace-scoped, network-validated project IDs only. # Raw project_ids may contain UUIDs from other workspaces; those are # absent from the `projects` queryset and therefore bypass the SECRET - # network check above (GHSA-45hc-q4mw-jhxm). + # network check above. validated_project_ids = [str(p.id) for p in projects] # If the user was already part of workspace @@ -222,8 +221,7 @@ class ProjectJoinEndpoint(BaseAPIView): # Require an authenticated session — the accepting user must be the # person who was invited. Without this check an attacker who knows the - # invitee email and obtains the token can hijack the project membership - # (GHSA-g36h-p63v-g9c7). + # invitee email and obtains the token can hijack the project membership. if not request.user.is_authenticated: return Response( {"error": "Authentication required to accept project invitation"}, diff --git a/apps/api/plane/tests/contract/app/test_project_invite_list_scope_app.py b/apps/api/plane/tests/contract/app/test_project_invite_list_scope_app.py index fc5518ba13..0c8ec497f8 100644 --- a/apps/api/plane/tests/contract/app/test_project_invite_list_scope_app.py +++ b/apps/api/plane/tests/contract/app/test_project_invite_list_scope_app.py @@ -4,7 +4,7 @@ """Contract tests for ``ProjectInvitationsViewset`` authorization. -Regression coverage for GHSA-r68c-48rr-m67f (WEB-8291). +Regression coverage for WEB-8291. The viewset declared no ``permission_classes`` (inheriting ``IsAuthenticated``) and only decorated ``create`` with ``@allow_permission([ROLE.ADMIN])``. The