mirror of
https://github.com/makeplane/plane.git
synced 2026-08-29 10:08:51 +02:00
fix(security): scope the duplicate ProjectMemberPermission POST branch too
Addresses review on #9596. plane/utils/permissions/project.py holds a second ProjectMemberPermission that, comments aside, was byte-identical to the one in plane/app/permissions. Its POST branch still checked workspace membership alone. It is imported (api/views/member.py) but its POST branch is currently unreachable: ProjectMemberListCreateAPIEndpoint.get_permissions() routes non-GET to ProjectAdminPermission, and the other consumer is GET-only. So this is a latent hazard rather than a second live vector — but two same-named classes that have already drifted make reintroduction easy, and this repo has previously had to patch the same duplication in the page permission classes. Both copies now carry a comment saying they must not drift. Also aligns the deploy-board 404 string with the module's existing wording ("Project does not exist", cf. base.py:230) rather than introducing a second phrasing for clients to handle. Co-authored-by: Plane AI <noreply@plane.so>
This commit is contained in:
@@ -565,7 +565,7 @@ class DeployBoardViewSet(BaseViewSet):
|
||||
# caller could aim their own workspace at another tenant's project id.
|
||||
# Defence in depth: the permission class now binds both.
|
||||
if not Project.objects.filter(pk=project_id, workspace__slug=slug).exists():
|
||||
return Response({"error": "Project not found"}, status=status.HTTP_404_NOT_FOUND)
|
||||
return Response({"error": "Project does not exist"}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
project_deploy_board, _ = DeployBoard.objects.get_or_create(
|
||||
entity_name="project", entity_identifier=project_id, project_id=project_id
|
||||
|
||||
@@ -66,12 +66,16 @@ class ProjectMemberPermission(BasePermission):
|
||||
project_id=view.project_id,
|
||||
is_active=True,
|
||||
).exists()
|
||||
## Only workspace owners or admins can create the projects
|
||||
# Scope POST to the URL project, as the other two branches already do.
|
||||
# A workspace-only check would let any member create sub-resources in a
|
||||
# project they do not belong to. Kept identical to the copy in
|
||||
# app/permissions/project.py — the two must not drift.
|
||||
if request.method == "POST":
|
||||
return WorkspaceMember.objects.filter(
|
||||
return ProjectMember.objects.filter(
|
||||
workspace__slug=view.workspace_slug,
|
||||
member=request.user,
|
||||
role__in=[ROLE.ADMIN.value, ROLE.MEMBER.value],
|
||||
project_id=view.project_id,
|
||||
is_active=True,
|
||||
).exists()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user