From 28ae25b564351abaf8b36d4a3ba6d32f80fbf075 Mon Sep 17 00:00:00 2001 From: Manish Gupta <59428681+mguptahub@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:35:10 +0530 Subject: [PATCH] [WEB-7847] fix: enforce workspace membership on entity-search endpoint (#9296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: enforce workspace membership on entity-search endpoint (GHSA-32q3-mqpc-3mhv) SearchEndpoint required authentication but did not verify the requesting user was a member of the queried workspace. Any authenticated Plane user could enumerate members across workspaces they don't belong to by guessing slugs. Add a WorkspaceMember guard at the top of get() — returns 403 if the user is not an active member of the target workspace. Brings OSS to parity with EE, which already had this protection via @can(WorkspacePermissions.VIEW). Co-authored-by: Plane AI * refactor(security): replace inline WS membership check with WorkspaceUserPermission Use the existing WorkspaceUserPermission permission class on SearchEndpoint instead of a manual WorkspaceMember.objects.filter() guard inside the method body. Enforcement behaviour is unchanged (GHSA-32q3-mqpc-3mhv). Co-authored-by: Plane AI --------- Co-authored-by: Plane AI --- apps/api/plane/app/views/search/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/api/plane/app/views/search/base.py b/apps/api/plane/app/views/search/base.py index 3bfbecaaff..1aff9d6c75 100644 --- a/apps/api/plane/app/views/search/base.py +++ b/apps/api/plane/app/views/search/base.py @@ -28,6 +28,7 @@ from rest_framework.response import Response # Module imports from plane.app.views.base import BaseAPIView +from plane.app.permissions import WorkspaceUserPermission from plane.db.models import ( Workspace, Project, @@ -302,6 +303,8 @@ class GlobalSearchEndpoint(BaseAPIView): class SearchEndpoint(BaseAPIView): + permission_classes = (WorkspaceUserPermission,) + def get(self, request, slug): query = request.query_params.get("query", False) query_types = request.query_params.get("query_type", "user_mention").split(",")