Skip to content

Commit 587fe76

Browse files
fix: prevent privilege escalation in project member role updates (GHSA-494h-3rcq-5g3c) (#8833)
Restrict role modification in ProjectMemberViewSet.partial_update to Admins only and enforce that requesters cannot modify or assign roles equal to or higher than their own. Previously, Guests could demote Admins by exploiting a missing lower-bound check on role changes. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a18d90d commit 587fe76

1 file changed

Lines changed: 29 additions & 14 deletions

File tree

apps/api/plane/app/views/project/member.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -226,21 +226,36 @@ def partial_update(self, request, slug, project_id, pk):
226226
is_active=True,
227227
)
228228

229-
if workspace_role in [5] and int(request.data.get("role", project_member.role)) in [15, 20]:
230-
return Response(
231-
{"error": "You cannot add a user with role higher than the workspace role"},
232-
status=status.HTTP_400_BAD_REQUEST,
233-
)
229+
if "role" in request.data:
230+
# Only Admins can modify roles
231+
if requested_project_member.role < ROLE.ADMIN.value and not is_workspace_admin:
232+
return Response(
233+
{"error": "You do not have permission to update roles"},
234+
status=status.HTTP_403_FORBIDDEN,
235+
)
234236

235-
if (
236-
"role" in request.data
237-
and int(request.data.get("role", project_member.role)) > requested_project_member.role
238-
and not is_workspace_admin
239-
):
240-
return Response(
241-
{"error": "You cannot update a role that is higher than your own role"},
242-
status=status.HTTP_400_BAD_REQUEST,
243-
)
237+
# Cannot modify a member whose role is equal to or higher than your own
238+
if project_member.role >= requested_project_member.role and not is_workspace_admin:
239+
return Response(
240+
{"error": "You cannot update the role of a member with a role equal to or higher than your own"},
241+
status=status.HTTP_403_FORBIDDEN,
242+
)
243+
244+
new_role = int(request.data.get("role"))
245+
246+
# Cannot assign a role equal to or higher than your own
247+
if new_role >= requested_project_member.role and not is_workspace_admin:
248+
return Response(
249+
{"error": "You cannot assign a role equal to or higher than your own"},
250+
status=status.HTTP_403_FORBIDDEN,
251+
)
252+
253+
# Cannot assign a role higher than the target's workspace role
254+
if workspace_role in [5] and new_role in [15, 20]:
255+
return Response(
256+
{"error": "You cannot add a user with role higher than the workspace role"},
257+
status=status.HTTP_400_BAD_REQUEST,
258+
)
244259

245260
serializer = ProjectMemberSerializer(project_member, data=request.data, partial=True)
246261

0 commit comments

Comments
 (0)