fix(incidents): Sync Slack participants before visibility check for private incidents#253
Draft
rgibert wants to merge 1 commit into
Draft
fix(incidents): Sync Slack participants before visibility check for private incidents#253rgibert wants to merge 1 commit into
rgibert wants to merge 1 commit into
Conversation
…rivate incidents The UI views checked visibility before syncing participants from Slack, causing 404s for channel members who hadn't been synced to the DB yet. Meanwhile, Slack commands had no visibility check at all, so channel members could interact with private incidents via /inc but not view them in the Firetower UI. Add a _get_visible_incident helper that tries the normal visibility filter first, then falls back to a force-sync from Slack for private incidents before re-checking visibility. This ensures channel members are recognised on their first UI visit. Refs LINEAR-RELENG-832 Co-Authored-By: Claude <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/Z34J4fwlHa2-tleFcG8vgI7ko2aMzMxOpyE6yfvdj5Y
| queryset = filter_visible_to_user(self.get_queryset(), self.request.user) | ||
|
|
||
| obj = get_object_or_404(queryset, id=numeric_id) | ||
| obj = _get_visible_incident(self.get_queryset(), numeric_id, self.request.user) |
There was a problem hiding this comment.
Unauthenticated-actor-scoped abuse: any authenticated user can trigger unlimited force Slack syncs on private incidents via SyncIncidentParticipantsView
Any authenticated user who knows a private incident's numeric ID can POST to /api/incidents/{id}/sync-participants/ and trigger Slack API calls unconditionally — _get_visible_incident force-syncs participants before confirming the caller has access, and no throttle class is configured on this view. For a newly-visible caller, two force syncs fire per request (one inside _get_visible_incident, one in post()); for an unrelated caller the Slack sync still fires before returning 404.
Evidence
_get_visible_incident(line 82) callssync_incident_participants_from_slack(incident, force=True)for every private incident where the caller fails the initial visibility filter — before confirming the caller has any legitimate access.SyncIncidentParticipantsView.post()(line 368) callssync_incident_participants_from_slack(incident, force=True)again afterget_object()returns, so a newly-synced caller triggers two force syncs in one request.SyncIncidentParticipantsViewdeclarespermission_classes = [IncidentPermission](authenticated only) but defines nothrottle_classes, and the view docstring confirms it 'bypasses throttle (force=True)'.- A caller who does not become visible after the first sync still gets a 404, but the Slack API call already occurred — this path can be triggered by any authenticated user for any private incident ID via brute-force.
Also found at 2 additional locations
src/firetower/incidents/views.py:103-106src/firetower/incidents/tests/test_views.py:1893
Identified by Warden security-review · 5H9-RY9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The UI views checked
filter_visible_to_user()before syncing participants from Slack, causing 404s for channel members whose participant records hadn't been synced to the DB yet. Meanwhile, Slack commands (e.g./inc update) useget_incident_from_channel()which has no visibility check at all -- so a user could interact with a private incident via Slack but get a 404 when trying to view it in Firetower.Adds a
_get_visible_incident()helper that tries the normal visibility filter first (fast path), then for private incidents, force-syncs participants from Slack and re-checks visibility before returning 404. This ensures channel members are recognised on their first UI visit. The fallback path only fires for authenticated users on private incidents where they aren't already a participant/captain/reporter, so the Slack API cost is minimal.Updated views:
IncidentDetailUIView,ActionItemListView,SyncActionItemsView,SyncIncidentParticipantsView.Refs LINEAR-RELENG-832
Agent transcript: https://claudescope.sentry.dev/share/vrooxZ-Kyb0pEjwNrvGOcI0W8sq0EcAuXNWsrfmrCKQ