fix: Member Information Disclosure via Public Endpoint#8646
fix: Member Information Disclosure via Public Endpoint#8646sriramveeraghanta merged 1 commit intopreviewfrom
Conversation
📝 WalkthroughWalkthroughThe changes remove unused fields (member__first_name, member__last_name, project, workspace) from the TPublicMember type across the API and TypeScript type definitions. An anchor validation guard was added to the ProjectMembersEndpoint to return 404 when the DeployBoard is missing. Changes
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR hardens the public “project members” endpoint used by the Space (public/published) experience by preventing invalid-anchor crashes and reducing exposed member/project/workspace data to only what the frontend consumes.
Changes:
- Add missing deploy board existence validation in the public members endpoint (return 404 on invalid anchor).
- Reduce the members payload to avoid exposing unused PII/IDs (remove first/last name, project UUID, workspace UUID).
- Align TS typings with the tightened API response shape.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| apps/api/plane/space/views/project.py | Adds invalid-anchor handling and limits returned fields from the public members listing. |
| packages/types/src/users.ts | Updates TPublicMember to match the new API response shape. |
| apps/space/core/types/member.d.ts | Updates Space app’s TPublicMember definition to match the new API response shape. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/api/plane/space/views/project.py`:
- Line 69: ProjectMembersEndpoint omits the entity_name filter allowing
cross-entity member disclosure; update the DeployBoard lookup in
ProjectMembersEndpoint to include entity_name="project" so it only resolves
project deploy boards (replace DeployBoard.objects.filter(anchor=anchor).first()
with a filtered query including entity_name="project"), ensuring subsequent use
of deploy_board.project returns members only for project-scoped boards.
---
Duplicate comments:
In `@apps/space/core/types/member.d.ts`:
- Around line 1-6: TPublicMember is duplicated here; remove the local type and
instead import and re-export the canonical TPublicMember from the shared package
(packages/types) so apps/space uses the single source of truth; update
apps/space/core/types/member.d.ts to import { TPublicMember } from
'packages/types' (or the package's public path) and export it, ensuring you
adopt the canonical nullability for member__avatar as defined in
packages/types/src/users.ts so the nullability matches the shared type.
| @@ -67,6 +67,11 @@ class ProjectMembersEndpoint(BaseAPIView): | |||
|
|
|||
| def get(self, request, anchor): | |||
| deploy_board = DeployBoard.objects.filter(anchor=anchor).first() | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 1. Check DeployBoard model definition and entity_name field
echo "=== DeployBoard Model Definition ==="
rg -n "class DeployBoard" --type py -A 30 apps/api/plane/db/models/
echo ""
echo "=== entity_name field constraints ==="
rg -n "entity_name" --type py -B 2 -A 2 apps/api/plane/db/models/ | head -60Repository: makeplane/plane
Length of output: 7389
🏁 Script executed:
#!/bin/bash
# 2. Check the specific file to see all DeployBoard lookups
echo "=== All DeployBoard lookups in project.py ==="
rg -n "DeployBoard" --type py -B 2 -A 2 apps/api/plane/space/views/project.pyRepository: makeplane/plane
Length of output: 1775
🏁 Script executed:
#!/bin/bash
# 3. Verify lines 23, 37, 59, and 69 to see the exact filter patterns
echo "=== Lines around 23, 37, 59, 69 in project.py ==="
sed -n '20,30p' apps/api/plane/space/views/project.py
echo "---"
sed -n '34,42p' apps/api/plane/space/views/project.py
echo "---"
sed -n '56,64p' apps/api/plane/space/views/project.py
echo "---"
sed -n '66,78p' apps/api/plane/space/views/project.pyRepository: makeplane/plane
Length of output: 1633
🏁 Script executed:
#!/bin/bash
# 4. Check what entity types can have deploy boards
echo "=== Possible entity_name values and where they're used ==="
rg "entity_name\s*=" --type py apps/api/plane/ | grep -E "(project|cycle|module)" | head -20Repository: makeplane/plane
Length of output: 2911
Missing entity_name="project" filter on line 69 allows unauthorized member disclosure.
The ProjectMembersEndpoint is the only endpoint in this file that omits the entity_name="project" filter. Since the anchor field is globally unique, an attacker can supply an anchor for a non-project deploy board (e.g., a cycle or module board that also has a project FK). The endpoint will still resolve deploy_board.project and return the full member list—circumventing the intended access control for project-specific boards.
Every other endpoint in this file and across the space views explicitly filters by entity_name="project". This endpoint must do the same.
🛡️ Proposed fix
- deploy_board = DeployBoard.objects.filter(anchor=anchor).first()
+ deploy_board = DeployBoard.objects.filter(anchor=anchor, entity_name="project").first()📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| deploy_board = DeployBoard.objects.filter(anchor=anchor).first() | |
| deploy_board = DeployBoard.objects.filter(anchor=anchor, entity_name="project").first() |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/api/plane/space/views/project.py` at line 69, ProjectMembersEndpoint
omits the entity_name filter allowing cross-entity member disclosure; update the
DeployBoard lookup in ProjectMembersEndpoint to include entity_name="project" so
it only resolves project deploy boards (replace
DeployBoard.objects.filter(anchor=anchor).first() with a filtered query
including entity_name="project"), ensuring subsequent use of
deploy_board.project returns members only for project-scoped boards.
|
Please Publish the report from security tab from CVE part! |
Description
Type of Change
Summary by CodeRabbit
Bug Fixes
Refactor