Skip to content

feat(developer-settings): add webhook_headers backend support#116901

Closed
sentry-junior[bot] wants to merge 28 commits into
masterfrom
feat/webhook-headers-backend
Closed

feat(developer-settings): add webhook_headers backend support#116901
sentry-junior[bot] wants to merge 28 commits into
masterfrom
feat/webhook-headers-backend

feat(developer-settings): add webhook_headers backend support

ddb61af
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed Jun 4, 2026 in 22m 22s

3 issues

High

webhookHeaders (potentially containing auth secrets) returned unconditionally to any authenticated user - `src/sentry/sentry_apps/api/serializers/sentry_app.py:150`

Move webhookHeaders inside the owner-gated block so it is only returned to members of the owning org or elevated users, matching the same protection applied to clientId and clientSecret.

Also found at:

  • src/sentry/sentry_apps/api/serializers/sentry_app.py:49
  • src/sentry/sentry_apps/logic.py:117
  • src/sentry/apidocs/examples/sentry_app_examples.py:108
webhookHeaders exposed without masking in API responses, leaking potential auth tokens to all authenticated users - `src/sentry/apidocs/examples/sentry_app_examples.py:108-141`

Custom webhook headers (which may contain Authorization: Bearer <token> or similar credentials) are returned unconditionally in SentryAppSerializer.serialize() at api/serializers/sentry_app.py:150 without the owner-membership gate that protects clientId/clientSecret; any authenticated user can retrieve them via GET /api/0/apps/?status=published.

Also found at:

  • src/sentry/sentry_apps/api/serializers/sentry_app.py:47
  • src/sentry/sentry_apps/api/serializers/sentry_app.py:150
  • src/sentry/sentry_apps/logic.py:352
  • src/sentry/sentry_apps/logic.py:436
  • src/sentry/sentry_apps/services/app/model.py:88
  • src/sentry/sentry_apps/services/app/serial.py:44
  • src/sentry/sentry_apps/logic.py:141
  • src/sentry/sentry_apps/models/sentry_app.py:129

Medium

Custom webhook headers exposed unmasked in GET responses for published Sentry Apps - `src/sentry/sentry_apps/api/endpoints/sentry_apps.py:137`

SentryAppSerializer returns webhookHeaders verbatim in the GET response for any Sentry App, and SentryAppPermission.has_object_permission lets any authenticated user GET a published app's details. Since webhook_headers is designed to carry per-app credentials (e.g. Authorization: Bearer ...), any Sentry user can read another org's webhook secrets via GET /api/0/sentry-apps/{slug}/. Mask the values like clientSecret does, or restrict exposure to org members with org:write.

Also found at:

  • src/sentry/sentry_apps/api/serializers/sentry_app.py:48
  • src/sentry/sentry_apps/api/serializers/sentry_app.py:150
  • src/sentry/sentry_apps/logic.py:117
  • src/sentry/sentry_apps/logic.py:352
  • src/sentry/sentry_apps/services/app/model.py:88
  • tests/sentry/sentry_apps/api/endpoints/test_sentry_apps.py:762-766
6 skills analyzed
Skill Findings Duration Cost
security-review 1 13m 49s $6.28
sentry-backend-bugs 0 2m 45s $1.22
wrdn-pii 0 11m 32s $0.28
wrdn-authz 1 12m 16s $1.85
wrdn-code-execution 0 12m 21s $0.34
wrdn-data-exfil 1 18m 1s $4.28

⏱ 70m 44s · 12.2M in / 254.5k out · $14.24