← All writeups
Medium Bugcrowd · Mattermost Duplicate

The Sibling That Forgot the Check: Missing Authorization on Jira Subscription-Template Endpoints (Mattermost)

access-controlidorauthorizationmattermostsibling-path-diffing

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}getSubscriptionTemplatesByIDremoveSubscriptionTemplate (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

  1. As any normal Mattermost user, run /jira connect to link your own Jira account — no special role needed.
  2. Harvest every template ID instance-wide: GET /plugins/jira/api/v2/subscription-templates?instance_id=<jiraURL>.
  3. Delete any admin-created template: DELETE /plugins/jira/api/v2/subscription-templates/<id>?instance_id=<jiraURL>&project_key=<x>, or overwrite it with a PUT.
  4. The template is deleted/modified despite you lacking the RolesAllowedToEditJiraSubscriptions role.

# 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.

# References