The Sibling That Forgot the Check: Missing Authorization on Jira Subscription-Template Endpoints (Mattermost)
By Kavennesh Balachandar · Bugcrowd · Mattermost Bug Bounty Program
# TL;DR
The four subscription-template endpoints in mattermost-plugin-jira are wrapped
in checkAuth only — they require a logged-in user with a Jira connection but
perform no channel, permission, or ownership check. Every channel-subscription
handler, by contrast, calls hasPermissionToManageSubscription, which enforces
the configured RolesAllowedToEditJiraSubscriptions admin gate. So any connected
Jira user with no admin role can enumerate, read, overwrite, and delete every
subscription template across the whole instance. Severity: Medium (P3),
CVSS ~6.3. This is a textbook "sibling-path diffing" find — the vulnerable
handlers sit right next to correct ones that do the check.
# The methodology: diff the siblings
My most productive technique on mature plugin codebases is to find a family of handlers that should share an authorization check, then look for the one that doesn't. When a prior hardening pass adds a permission gate to some endpoints in a group but misses others, the miss isn't a design decision — it's an oversight, and an omission sitting next to a present check is very dup-resistant evidence.
Mattermost's Jira plugin has exactly such a family: channel-subscription handlers and subscription-template handlers, structurally parallel, in the same file.
# The vulnerable endpoints
mattermost-plugin-jira — routes at server/http.go:168-171, handlers in
server/subscribe.go:
GET /subscription-templates → httpGetSubscriptionTemplates (subscribe.go:1397)
POST /subscription-templates → httpCreateSubscriptionTemplate (subscribe.go:1469)
PUT /subscription-templates → httpEditSubscriptionTemplates (subscribe.go:1439)
DELETE /subscription-templates/{id} → httpDeleteSubscriptionTemplate (subscribe.go:1499)
All four are wrapped in checkAuth and nothing else. The delete path goes
straight from the attacker-supplied {id} → getSubscriptionTemplatesByID →
removeSubscriptionTemplate (subscribe.go:1518-1528); the only identity call is
getClient, which merely verifies the attacker's own Jira connection.
# The check the siblings enforce (and these don't)
Every channel-subscription handler calls, at
subscribe.go:1179,1242,1255,1329,1383:
hasPermissionToManageSubscription(instanceID, userID, channelID)
which enforces RolesAllowedToEditJiraSubscriptions (default system_admin).
The four template handlers omit it entirely. That's the whole bug: a permission
gate present on one half of a sibling group, absent on the other.
# Steps to reproduce
- As any normal Mattermost user, run
/jira connectto link your own Jira account — no special role needed. - Harvest every template ID instance-wide:
GET /plugins/jira/api/v2/subscription-templates?instance_id=<jiraURL>. - Delete any admin-created template:
DELETE /plugins/jira/api/v2/subscription-templates/<id>?instance_id=<jiraURL>&project_key=<x>, or overwrite it with aPUT. - The template is deleted/modified despite you lacking the
RolesAllowedToEditJiraSubscriptionsrole.
# Impact and severity
Any connected Jira user with no admin role can enumerate, read, overwrite, and delete all channel-subscription templates across the instance — cross-user destructive write/delete of admin-owned configuration, plus disclosure of template config (JQL, project keys, channel IDs), bypassing the subscription-management admin gate.
Severity: Medium — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L (~6.3) / P3.
Capped at P3 because templates are verified not to be in the webhook posting
path — so this is not a notification hijack or issue-data exfiltration, but
destructive tampering with admin-owned config.
# Remediation
Add hasPermissionToManageSubscription(instanceID, mattermostUserID, template.ChannelID) — the same gate the channel-subscription handlers use — at
the start of all four template handlers, resolving the channel from the stored
template for edit/delete.
# Disclosure timeline
- 2026-06-26 — Reported to Mattermost via Bugcrowd.
- Closed as duplicate / not applicable.
- Public disclosure pending program approval.