Confidential/internal ticket titles leak to Matrix on create/status-change (NotificationHelper missing visibility check) #46

Open
opened 2026-08-31 21:36:16 -04:00 by jared · 0 comments
Owner

Severity: High

helpers/NotificationHelper.php (~lines 48-89), sendTicketNotification() and sendStatusChangeNotification() — every caller (controllers/TicketController.php:159, create_ticket_api.php:336/389/487, cron/create_recurring_tickets.php:99, api/update_ticket.php:265, api/ticket_status_api.php:169) invokes these with no visibility check and no visibility parameter. The ticket title (plus category/type/priority on creation) is always sent to the shared MATRIX_NOTIFY_USERS list and posted to the hookshot webhook, regardless of whether the ticket is confidential or internal.

This is inconsistent with redaction logic that already exists a few functions away in the same file: sendCommentNotification() and notifyWatchers() both explicitly null out the comment preview for non-public tickets, with a comment explaining why ("never post the comment body... to the shared notify list"). That same care wasn't applied to ticket-created/status-changed notifications.

Impact: Creating or changing the status of a confidential ticket broadcasts its title to a shared Matrix room, defeating the purpose of the Confidential visibility level.

Fix: Thread $ticket['visibility'] through both functions and redact/suppress the title for non-public tickets the same way comment previews already are.

**Severity:** High `helpers/NotificationHelper.php` (~lines 48-89), `sendTicketNotification()` and `sendStatusChangeNotification()` — every caller (`controllers/TicketController.php:159`, `create_ticket_api.php:336/389/487`, `cron/create_recurring_tickets.php:99`, `api/update_ticket.php:265`, `api/ticket_status_api.php:169`) invokes these with no visibility check and no visibility parameter. The ticket title (plus category/type/priority on creation) is always sent to the shared `MATRIX_NOTIFY_USERS` list and posted to the hookshot webhook, regardless of whether the ticket is `confidential` or `internal`. This is inconsistent with redaction logic that already exists a few functions away in the same file: `sendCommentNotification()` and `notifyWatchers()` both explicitly null out the comment preview for non-public tickets, with a comment explaining why ("never post the comment body... to the shared notify list"). That same care wasn't applied to ticket-created/status-changed notifications. **Impact:** Creating or changing the status of a confidential ticket broadcasts its title to a shared Matrix room, defeating the purpose of the Confidential visibility level. **Fix:** Thread `$ticket['visibility']` through both functions and redact/suppress the title for non-public tickets the same way comment previews already are.
jared added the notificationspriority/highsecurity labels 2026-09-08 10:15:45 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/tinker_tickets#46