fix(space): IssueVotePublicViewSet.create() does not enforce is_votes_enabled board setting
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 59.6k
- Forks
- 5.8k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 49
Description
Summary
IssueVotePublicViewSet.create() allows users to cast votes even when voting is administratively disabled on the public board (is_votes_enabled = False).
Root Cause
Every other create() method in the public board views guards against its feature flag before writing:
# IssueCommentPublicViewSet.create()
if not project_deploy_board.is_comments_enabled:
return Response({"error": "Comments are not enabled"}, status=400)
# IssueReactionPublicViewSet.create()
if not project_deploy_board.is_reactions_enabled:
return Response({"error": "Reactions are not enabled"}, status=400)
IssueVotePublicViewSet.create() has no equivalent check. Note: get_queryset() does check is_votes_enabled, so vote listing is correctly gated. Only the write path is missing the gate.
Impact
- Security impact: None — functional/administrative enforcement gap only.
- Functional impact: Board administrators who disable voting cannot prevent authenticated users from casting votes via the API.
Recommended Fix
def create(self, request, anchor, issue_id):
project_deploy_board = DeployBoard.objects.get(anchor=anchor, entity_name="project")
if not project_deploy_board.is_votes_enabled:
return Response(
{"error": "Votes are not enabled for this project board"},
status=status.HTTP_400_BAD_REQUEST,
)
...
Affected File
apps/api/plane/space/views/issue.py — IssueVotePublicViewSet.create()
Related
Identified during security audit of PR #9498. Pre-existing issue, not introduced by that PR.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Open apps/api/plane/space/views/issue.py and inspect IssueVotePublicViewSet.create(), then compare its write path with IssueCommentPublicViewSet.create() and IssueReactionPublicViewSet.create(). Done means disabled boards reject vote creation with the specified 400 response while enabled boards retain their existing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 86/100