Summary
Security audit identified 3 findings (1 MEDIUM, 2 LOW). Overall Spirit is well-secured with consistent use of decorators and access-checked querysets. The findings involve missing topic access checks on poll and bookmark endpoints.
Findings
1. MEDIUM: Poll Vote and Voters Missing Topic Access Check
File: spirit/comment/poll/views.py:34-78
The vote() and voters() views do not check whether the requesting user has access to the topic the poll belongs to. Both use CommentPoll.objects.unremoved() which only filters by is_removed=False, not by topic access. The developer acknowledged this with TODO comments:
@require_POST
def vote(request, pk):
# TODO: check if user has access to this topic/poll
poll = get_object_or_404(CommentPoll.objects.unremoved(), pk=pk)
1-of-N: Other endpoints consistently use access-checked querysets:
comment/views.py:publish() uses Topic.objects.opened().for_access(user)
comment/views.py:update() uses Comment.objects.for_update_or_404(pk, request.user)
comment/history/views.py:detail() uses Comment.objects.for_access(request.user)
Impact: Any authenticated user can vote on polls in private topics they cannot access, and view voter lists for private topic polls.
2. LOW: Comment Find Leaks Private Topic Metadata
File: spirit/comment/views.py:107-118
find() retrieves any comment by PK (including comments on private topics) and redirects to the topic URL, leaking the topic title via URL slug.
1-of-N: comment/history/views.py:detail() uses Comment.objects.for_access(request.user).
3. LOW: Bookmark Create Missing Topic Access Check
File: spirit/comment/bookmark/views.py:13-26
create() allows bookmarking any topic including private ones.
1-of-N: topic/notification/views.py:create() uses Topic.objects.for_access(request.user).
Recommended Fix
Add for_access(request.user) filtering to poll, comment find, and bookmark querysets, consistent with the pattern used throughout the rest of the codebase.
Reported by Lighthouse Security Research (lighthouse1212.com)
Summary
Security audit identified 3 findings (1 MEDIUM, 2 LOW). Overall Spirit is well-secured with consistent use of decorators and access-checked querysets. The findings involve missing topic access checks on poll and bookmark endpoints.
Findings
1. MEDIUM: Poll Vote and Voters Missing Topic Access Check
File:
spirit/comment/poll/views.py:34-78The
vote()andvoters()views do not check whether the requesting user has access to the topic the poll belongs to. Both useCommentPoll.objects.unremoved()which only filters byis_removed=False, not by topic access. The developer acknowledged this with TODO comments:1-of-N: Other endpoints consistently use access-checked querysets:
comment/views.py:publish()usesTopic.objects.opened().for_access(user)comment/views.py:update()usesComment.objects.for_update_or_404(pk, request.user)comment/history/views.py:detail()usesComment.objects.for_access(request.user)Impact: Any authenticated user can vote on polls in private topics they cannot access, and view voter lists for private topic polls.
2. LOW: Comment Find Leaks Private Topic Metadata
File:
spirit/comment/views.py:107-118find()retrieves any comment by PK (including comments on private topics) and redirects to the topic URL, leaking the topic title via URL slug.1-of-N:
comment/history/views.py:detail()usesComment.objects.for_access(request.user).3. LOW: Bookmark Create Missing Topic Access Check
File:
spirit/comment/bookmark/views.py:13-26create()allows bookmarking any topic including private ones.1-of-N:
topic/notification/views.py:create()usesTopic.objects.for_access(request.user).Recommended Fix
Add
for_access(request.user)filtering to poll, comment find, and bookmark querysets, consistent with the pattern used throughout the rest of the codebase.Reported by Lighthouse Security Research (lighthouse1212.com)